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
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) \
42 ok(expect_ ##func, "unexpected call " #func "\n"); \
43 expect_ ## func = FALSE; \
44 called_ ## func = TRUE; \
47 #define CHECK_EXPECT2(func) \
49 ok(expect_ ##func, "unexpected call " #func "\n"); \
50 called_ ## func = TRUE; \
53 #define CHECK_CALLED(func) \
55 ok(called_ ## func, "expected " #func "\n"); \
56 expect_ ## func = called_ ## func = FALSE; \
59 #define CHECK_NOT_CALLED(func) \
61 ok(!called_ ## func, "unexpected " #func "\n"); \
62 expect_ ## func = called_ ## func = FALSE; \
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);
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[] = {
138 static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2)
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);
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)) {
167 return E_NOINTERFACE;
170 static ULONG WINAPI Protocol_AddRef(IInternetProtocol *iface)
175 static ULONG WINAPI Protocol_Release(IInternetProtocol *iface)
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;
189 static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',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
209 "bindf=%08x\n", bindf);
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) {
220 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
221 BINDSTATUS_DIRECTBIND, NULL);
223 "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
227 SET_EXPECT(OnProgress_SENDINGREQUEST);
228 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
229 BINDSTATUS_SENDINGREQUEST, &null_char);
231 "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
232 CHECK_CALLED(OnProgress_SENDINGREQUEST);
237 if(test_protocol == FILE_TEST) {
238 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
239 BINDSTATUS_CACHEFILENAMEAVAILABLE, &null_char);
241 "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
243 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
244 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
245 BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, wszTextHtml);
247 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
248 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
250 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
251 BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);
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;
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);
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) {
284 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
285 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
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);
297 static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
298 PROTOCOLDATA *pProtocolData)
300 ok(0, "unexpected call\n");
304 static HRESULT WINAPI Protocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
307 ok(0, "unexpected call\n");
311 static HRESULT WINAPI Protocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
313 CHECK_EXPECT(Terminate);
314 ok(dwOptions == 0, "dwOptions=%d, expected 0\n", dwOptions);
318 static HRESULT WINAPI Protocol_Suspend(IInternetProtocol *iface)
320 ok(0, "unexpected call\n");
324 static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface)
326 ok(0, "unexpected call\n");
330 static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv,
331 ULONG cb, ULONG *pcbRead)
333 static const char data[] = "<HTML></HTML>";
342 ok(pv != NULL, "pv == NULL\n");
343 ok(cb != 0, "cb == 0\n");
344 ok(pcbRead != NULL, "pcbRead == NULL\n");
346 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
347 read += *pcbRead = sizeof(data)-1;
350 memcpy(pv, data, sizeof(data));
355 static HRESULT WINAPI Protocol_Seek(IInternetProtocol *iface,
356 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
358 ok(0, "unexpected call\n");
362 static HRESULT WINAPI Protocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
364 CHECK_EXPECT(LockRequest);
368 static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocol *iface)
370 CHECK_EXPECT(UnlockRequest);
374 static const IInternetProtocolVtbl ProtocolVtbl = {
375 Protocol_QueryInterface,
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)) {
401 ok(0, "unexpected call\n");
402 return E_NOINTERFACE;
405 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
410 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
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");
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");
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");
457 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
458 *pcbSecurityId = sizeof(sec_id);
462 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
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) {
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;
498 else if (IsEqualGUID(&IID_IHttpNegotiate2, riid))
500 CHECK_EXPECT(QueryInterface_IHttpNegotiate2);
501 *ppv = &HttpNegotiate;
505 return E_NOINTERFACE;
508 static ULONG WINAPI statusclb_AddRef(IBindStatusCallback *iface)
513 static ULONG WINAPI statusclb_Release(IBindStatusCallback *iface)
518 static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
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");
531 IMoniker_Release(mon);
536 static HRESULT WINAPI statusclb_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
538 ok(0, "unexpected call\n");
542 static HRESULT WINAPI statusclb_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
544 ok(0, "unexpected call\n");
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);
555 case BINDSTATUS_CONNECTING:
556 CHECK_EXPECT(OnProgress_CONNECTING);
558 case BINDSTATUS_SENDINGREQUEST:
559 CHECK_EXPECT(OnProgress_SENDINGREQUEST);
561 case BINDSTATUS_MIMETYPEAVAILABLE:
562 CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE);
563 ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
565 WideCharToMultiByte(CP_ACP, 0, szStatusText, -1, mime_type, sizeof(mime_type)-1, NULL, NULL);
567 case BINDSTATUS_BEGINDOWNLOADDATA:
568 CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
569 ok(szStatusText != NULL, "szStatusText == NULL\n");
571 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
572 ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
574 download_state = DOWNLOADING;
576 case BINDSTATUS_DOWNLOADINGDATA:
577 CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA);
578 ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
581 case BINDSTATUS_ENDDOWNLOADDATA:
582 CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
583 ok(szStatusText != NULL, "szStatusText == NULL\n");
585 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
586 ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
588 download_state = END_DOWNLOAD;
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");
596 todo_wine { ok(0, "unexpexted code %d\n", ulStatusCode); }
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;
616 static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
620 CHECK_EXPECT(GetBindInfo);
623 cbSize = pbindinfo->cbSize;
624 memset(pbindinfo, 0, cbSize);
625 pbindinfo->cbSize = cbSize;
630 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
631 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
638 CHECK_EXPECT2(OnDataAvailable);
639 ok(download_state == DOWNLOADING || download_state == END_DOWNLOAD,
640 "Download state was %d, expected DOWNLOADING or END_DOWNLOAD\n",
642 data_available = TRUE;
644 ok(pformatetc != NULL, "pformatetx == NULL\n");
646 if (mime_type[0]) todo_wine {
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",
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");
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);
671 ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
677 static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
679 ok(0, "unexpected call\n");
683 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
684 statusclb_QueryInterface,
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;
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",
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);
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;
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",
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",
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);
796 IUnknown_Release(unk);
799 IBindCtx_Release(bctx);
802 static void test_BindToStorage(int protocol, BOOL emul)
806 LPOLESTR display_name;
809 IBindStatusCallback *previousclb;
810 IUnknown *unk = (IUnknown*)0x00ff00ff;
813 test_protocol = protocol;
814 emulate_protocol = emul;
815 download_state = BEFORE_DOWNLOAD;
816 stopped_binding = FALSE;
817 data_available = FALSE;
820 SET_EXPECT(QueryInterface_IServiceProvider);
821 hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx);
822 ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n\n", hres);
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);
833 IBindStatusCallback_Release(previousclb);
835 hres = CreateURLMoniker(NULL, urls[test_protocol], &mon);
836 ok(SUCCEEDED(hres), "failed to create moniker: %08x\n", hres);
838 IBindCtx_Release(bctx);
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");
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) {
859 SET_EXPECT(UnlockRequest);
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" );
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");
894 ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
895 ok(unk != NULL, "unk == NULL\n");
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) {
911 CHECK_CALLED(UnlockRequest);
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);
921 CHECK_CALLED(OnProgress_FINDINGRESOURCE);
922 CHECK_CALLED(OnProgress_CONNECTING);
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)
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)
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)
975 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
981 static void test_BindToStorage_fail(void)
983 IMoniker *mon = NULL;
984 IBindCtx *bctx = NULL;
988 hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
989 ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
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);
1007 test_CreateAsyncBindCtx();
1008 test_CreateAsyncBindCtxEx();
1010 trace("synchronous http test...\n");
1011 test_BindToStorage(HTTP_TEST, FALSE);
1013 trace("synchronous file test...\n");
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");
1030 test_BindToStorage(ABOUT_TEST, FALSE);
1033 trace("emulated about test...\n");
1034 test_BindToStorage(ABOUT_TEST, TRUE);
1036 trace("file test...\n");
1038 test_BindToStorage(FILE_TEST, FALSE);
1039 DeleteFileW(wszIndexHtml);
1041 trace("emulated file test...\n");
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();