Don't crash if BindToStorage fails.
[wine/multimedia.git] / dlls / urlmon / tests / url.c
blobc8231d9b9a163459c54c88d7261321e3ed177974
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdarg.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "urlmon.h"
30 #include "wine/test.h"
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define CHECK_EXPECT(func) \
39 do { \
40 ok(expect_ ##func, "unexpected call\n"); \
41 expect_ ## func = FALSE; \
42 called_ ## func = TRUE; \
43 }while(0)
45 #define CHECK_EXPECT2(func) \
46 do { \
47 ok(expect_ ##func, "unexpected call\n"); \
48 called_ ## func = TRUE; \
49 }while(0)
51 #define CHECK_CALLED(func) \
52 do { \
53 ok(called_ ## func, "expected " #func "\n"); \
54 expect_ ## func = called_ ## func = FALSE; \
55 }while(0)
57 DEFINE_EXPECT(GetBindInfo);
58 DEFINE_EXPECT(OnStartBinding);
59 DEFINE_EXPECT(OnProgress_FINDINGRESOURCE);
60 DEFINE_EXPECT(OnProgress_CONNECTING);
61 DEFINE_EXPECT(OnProgress_SENDINGREQUEST);
62 DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE);
63 DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA);
64 DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA);
65 DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA);
66 DEFINE_EXPECT(OnStopBinding);
67 DEFINE_EXPECT(OnDataAvailable);
68 DEFINE_EXPECT(Start);
69 DEFINE_EXPECT(Read);
70 DEFINE_EXPECT(LockRequest);
71 DEFINE_EXPECT(Terminate);
72 DEFINE_EXPECT(UnlockRequest);
74 static const WCHAR TEST_URL_1[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','\0'};
75 static const WCHAR TEST_PART_URL_1[] = {'/','t','e','s','t','/','\0'};
77 static const WCHAR WINE_ABOUT_URL[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
78 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
79 static const WCHAR ABOUT_BLANK[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
82 static BOOL stopped_binding = FALSE, emulate_protocol = FALSE;
83 static DWORD read = 0;
85 static const LPCWSTR urls[] = {
86 WINE_ABOUT_URL,
87 ABOUT_BLANK
90 static enum {
91 HTTP_TEST,
92 ABOUT_TEST
93 } test_protocol;
95 static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2)
97 HRESULT hr;
98 IMoniker *mon1 = NULL;
99 IMoniker *mon2 = NULL;
101 hr = CreateURLMoniker(NULL, url1, &mon1);
102 ok(SUCCEEDED(hr), "failed to create moniker: 0x%08lx\n", hr);
103 if(SUCCEEDED(hr)) {
104 hr = CreateURLMoniker(mon1, url2, &mon2);
105 ok(SUCCEEDED(hr), "failed to create moniker: 0x%08lx\n", hr);
107 if(mon1) IMoniker_Release(mon1);
108 if(mon2) IMoniker_Release(mon2);
111 static void test_create(void)
113 test_CreateURLMoniker(TEST_URL_1, TEST_PART_URL_1);
116 static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
118 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
119 *ppv = iface;
120 return S_OK;
123 *ppv = NULL;
124 return E_NOINTERFACE;
127 static ULONG WINAPI Protocol_AddRef(IInternetProtocol *iface)
129 return 2;
132 static ULONG WINAPI Protocol_Release(IInternetProtocol *iface)
134 return 1;
137 static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
138 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
139 DWORD grfPI, DWORD dwReserved)
141 BINDINFO bindinfo, bi = {sizeof(bi), 0};
142 DWORD bindf;
143 HRESULT hres;
145 static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
147 CHECK_EXPECT(Start);
149 read = 0;
151 ok(szUrl && !lstrcmpW(szUrl, urls[test_protocol]), "wrong url\n");
152 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
153 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
154 ok(grfPI == 0, "grfPI=%ld, expected 0\n", grfPI);
155 ok(dwReserved == 0, "dwReserved=%ld, expected 0\n", dwReserved);
157 memset(&bindinfo, 0, sizeof(bindinfo));
158 bindinfo.cbSize = sizeof(bindinfo);
159 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
160 ok(hres == S_OK, "GetBindInfo failed: %08lx\n", hres);
161 ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA|
162 BINDF_FROMURLMON|BINDF_NEEDFILE),
163 "bindf=%08lx\n", bindf);
164 ok(!memcmp(&bindinfo, &bi, sizeof(bindinfo)), "wrong bindinfo\n");
166 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE,
167 wszTextHtml);
168 ok(hres == S_OK, "ReportProgress(BINDSTATUS_MIMETYPEAVAILABKE) failed: %08lx\n", hres);
170 SET_EXPECT(Read);
171 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
172 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
173 SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
174 SET_EXPECT(LockRequest);
175 SET_EXPECT(OnDataAvailable);
176 SET_EXPECT(OnStopBinding);
178 hres = IInternetProtocolSink_ReportData(pOIProtSink,
179 BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
180 13, 13);
181 ok(hres == S_OK, "ReportData failed: %08lx\n", hres);
182 CHECK_CALLED(Read);
183 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
184 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
185 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
186 CHECK_CALLED(LockRequest);
187 CHECK_CALLED(OnDataAvailable);
188 CHECK_CALLED(OnStopBinding);
190 IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
192 return S_OK;
195 static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
196 PROTOCOLDATA *pProtocolData)
198 ok(0, "unexpected call\n");
199 return E_NOTIMPL;
202 static HRESULT WINAPI Protocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
203 DWORD dwOptions)
205 ok(0, "unexpected call\n");
206 return E_NOTIMPL;
209 static HRESULT WINAPI Protocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
211 CHECK_EXPECT(Terminate);
212 ok(dwOptions == 0, "dwOptions=%ld, expected 0\n", dwOptions);
213 return S_OK;
216 static HRESULT WINAPI Protocol_Suspend(IInternetProtocol *iface)
218 ok(0, "unexpected call\n");
219 return E_NOTIMPL;
222 static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface)
224 ok(0, "unexpected call\n");
225 return E_NOTIMPL;
228 static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv,
229 ULONG cb, ULONG *pcbRead)
231 static const char data[] = "<HTML></HTML>";
233 CHECK_EXPECT2(Read);
235 if(read) {
236 *pcbRead = 0;
237 return S_FALSE;
240 ok(pv != NULL, "pv == NULL\n");
241 ok(cb != 0, "cb == 0\n");
242 ok(pcbRead != NULL, "pcbRead == NULL\n");
243 if(pcbRead) {
244 ok(*pcbRead == 0, "*pcbRead=%ld, expected 0\n", *pcbRead);
245 *pcbRead = 13;
246 read = 13;
248 if(pv)
249 memcpy(pv, data, sizeof(data));
251 return S_OK;
254 static HRESULT WINAPI Protocol_Seek(IInternetProtocol *iface,
255 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
257 ok(0, "unexpected call\n");
258 return E_NOTIMPL;
261 static HRESULT WINAPI Protocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
263 CHECK_EXPECT(LockRequest);
264 return S_OK;
267 static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocol *iface)
269 CHECK_EXPECT(UnlockRequest);
270 return S_OK;
273 static const IInternetProtocolVtbl ProtocolVtbl = {
274 Protocol_QueryInterface,
275 Protocol_AddRef,
276 Protocol_Release,
277 Protocol_Start,
278 Protocol_Continue,
279 Protocol_Abort,
280 Protocol_Terminate,
281 Protocol_Suspend,
282 Protocol_Resume,
283 Protocol_Read,
284 Protocol_Seek,
285 Protocol_LockRequest,
286 Protocol_UnlockRequest
289 static IInternetProtocol Protocol = { &ProtocolVtbl };
291 typedef struct {
292 const IBindStatusCallbackVtbl *lpVtbl;
293 LONG ref;
294 IBinding *pbind;
295 IStream *pstr;
296 } statusclb;
298 static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
300 if(emulate_protocol && IsEqualGUID(&IID_IInternetProtocol, riid)) {
301 *ppv = &Protocol;
302 return S_OK;
305 return E_NOINTERFACE;
308 static ULONG WINAPI statusclb_AddRef(IBindStatusCallback *iface)
310 return InterlockedIncrement(&((statusclb*)iface)->ref);
313 static ULONG WINAPI statusclb_Release(IBindStatusCallback *iface)
315 statusclb *This = (statusclb*)iface;
316 ULONG ref;
317 ref = InterlockedDecrement(&This->ref);
318 if(!ref)
319 HeapFree(GetProcessHeap(), 0, This);
320 return ref;
323 static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
324 IBinding *pib)
326 statusclb *This = (statusclb*)iface;
327 HRESULT hres;
328 IMoniker *mon;
330 CHECK_EXPECT(OnStartBinding);
332 This->pbind = pib;
333 ok(pib != NULL, "pib should not be NULL\n");
334 if(pib)
335 IBinding_AddRef(pib);
337 hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon);
338 ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n");
339 if(SUCCEEDED(hres))
340 IMoniker_Release(mon);
342 return S_OK;
345 static HRESULT WINAPI statusclb_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
347 ok(0, "unexpected call\n");
348 return E_NOTIMPL;
351 static HRESULT WINAPI statusclb_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
353 ok(0, "unexpected call\n");
354 return E_NOTIMPL;
357 static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
358 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
360 switch(ulStatusCode) {
361 case BINDSTATUS_FINDINGRESOURCE:
362 CHECK_EXPECT(OnProgress_FINDINGRESOURCE);
363 break;
364 case BINDSTATUS_CONNECTING:
365 CHECK_EXPECT(OnProgress_CONNECTING);
366 break;
367 case BINDSTATUS_SENDINGREQUEST:
368 CHECK_EXPECT(OnProgress_SENDINGREQUEST);
369 break;
370 case BINDSTATUS_MIMETYPEAVAILABLE:
371 CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE);
372 break;
373 case BINDSTATUS_BEGINDOWNLOADDATA:
374 CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
375 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
376 break;
377 case BINDSTATUS_DOWNLOADINGDATA:
378 CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA);
379 break;
380 case BINDSTATUS_ENDDOWNLOADDATA:
381 CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
382 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
383 break;
384 default:
385 todo_wine { ok(0, "unexpexted code %ld\n", ulStatusCode); }
387 return S_OK;
390 static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
392 statusclb *This = (statusclb*)iface;
394 CHECK_EXPECT(OnStopBinding);
396 ok(SUCCEEDED(hresult), "Download failed: %08lx\n", hresult);
397 ok(szError == NULL, "szError should be NULL\n");
398 stopped_binding = TRUE;
399 IBinding_Release(This->pbind);
400 ok(This->pstr != NULL, "pstr should not be NULL here\n");
401 if(This->pstr)
402 IStream_Release(This->pstr);
404 return S_OK;
407 static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
409 DWORD cbSize;
411 CHECK_EXPECT(GetBindInfo);
413 *grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
414 cbSize = pbindinfo->cbSize;
415 memset(pbindinfo, 0, cbSize);
416 pbindinfo->cbSize = cbSize;
418 return S_OK;
421 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
422 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
424 statusclb *This = (statusclb*)iface;
425 HRESULT hres;
426 DWORD readed;
427 BYTE buf[512];
429 CHECK_EXPECT2(OnDataAvailable);
431 if(!This->pstr) {
432 ok(grfBSCF & BSCF_FIRSTDATANOTIFICATION, "pstr should be set when BSCF_FIRSTDATANOTIFICATION\n");
433 This->pstr = U(*pstgmed).pstm;
434 IStream_AddRef(This->pstr);
435 ok(This->pstr != NULL, "pstr should not be NULL here\n");
438 do hres = IStream_Read(This->pstr, buf, 512, &readed);
439 while(hres == S_OK);
440 ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08lx\n", hres);
442 return S_OK;
445 static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
447 ok(0, "unexpected call\n");
448 return E_NOTIMPL;
451 static const IBindStatusCallbackVtbl statusclbVtbl = {
452 statusclb_QueryInterface,
453 statusclb_AddRef,
454 statusclb_Release,
455 statusclb_OnStartBinding,
456 statusclb_GetPriority,
457 statusclb_OnLowResource,
458 statusclb_OnProgress,
459 statusclb_OnStopBinding,
460 statusclb_GetBindInfo,
461 statusclb_OnDataAvailable,
462 statusclb_OnObjectAvailable
465 static IBindStatusCallback* statusclb_create(void)
467 statusclb *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(statusclb));
468 ret->lpVtbl = &statusclbVtbl;
469 ret->ref = 1;
470 ret->pbind = NULL;
471 ret->pstr = NULL;
472 return (IBindStatusCallback*)ret;
475 static void test_CreateAsyncBindCtx(void)
477 IBindCtx *bctx = (IBindCtx*)0x0ff00ff0;
478 HRESULT hres;
479 ULONG ref;
480 BIND_OPTS bindopts;
481 IBindStatusCallback *bsc = statusclb_create();
483 hres = CreateAsyncBindCtx(0, NULL, NULL, &bctx);
484 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08lx\n", hres);
485 ok(bctx == (IBindCtx*)0x0ff00ff0, "bctx should not be changed\n");
487 hres = CreateAsyncBindCtx(0, NULL, NULL, NULL);
488 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08lx\n", hres);
490 hres = CreateAsyncBindCtx(0, bsc, NULL, &bctx);
491 ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08lx\n", hres);
492 if(FAILED(hres)) {
493 IBindStatusCallback_Release(bsc);
494 return;
497 bindopts.cbStruct = sizeof(bindopts);
498 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
499 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08lx\n", hres);
500 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
501 "bindopts.grfFlags = %08lx, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
502 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
503 "bindopts.grfMode = %08lx, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
504 bindopts.grfMode);
505 ok(bindopts.dwTickCountDeadline == 0,
506 "bindopts.dwTickCountDeadline = %08lx, expected: 0\n", bindopts.dwTickCountDeadline);
508 ref = IBindCtx_Release(bctx);
509 ok(ref == 0, "bctx should be destroyed here\n");
510 ref = IBindStatusCallback_Release(bsc);
511 ok(ref == 0, "bsc should be destroyed here\n");
514 static void test_CreateAsyncBindCtxEx(void)
516 IBindCtx *bctx = NULL, *bctx_arg = NULL;
517 IBindStatusCallback *bsc = statusclb_create();
518 BIND_OPTS bindopts;
519 HRESULT hres;
521 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, NULL, 0);
522 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed: %08lx, expected E_INVALIDARG\n", hres);
524 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
525 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08lx\n", hres);
527 if(SUCCEEDED(hres)) {
528 bindopts.cbStruct = sizeof(bindopts);
529 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
530 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08lx\n", hres);
531 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
532 "bindopts.grfFlags = %08lx, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
533 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
534 "bindopts.grfMode = %08lx, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
535 bindopts.grfMode);
536 ok(bindopts.dwTickCountDeadline == 0,
537 "bindopts.dwTickCountDeadline = %08lx, expected: 0\n", bindopts.dwTickCountDeadline);
539 IBindCtx_Release(bctx);
542 CreateBindCtx(0, &bctx_arg);
543 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
544 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08lx\n", hres);
546 if(SUCCEEDED(hres)) {
547 bindopts.cbStruct = sizeof(bindopts);
548 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
549 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08lx\n", hres);
550 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
551 "bindopts.grfFlags = %08lx, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
552 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
553 "bindopts.grfMode = %08lx, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
554 bindopts.grfMode);
555 ok(bindopts.dwTickCountDeadline == 0,
556 "bindopts.dwTickCountDeadline = %08lx, expected: 0\n", bindopts.dwTickCountDeadline);
558 IBindCtx_Release(bctx);
561 IBindCtx_Release(bctx_arg);
563 hres = CreateAsyncBindCtxEx(NULL, 0, bsc, NULL, &bctx, 0);
564 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08lx\n", hres);
566 if(SUCCEEDED(hres))
567 IBindCtx_Release(bctx);
569 IBindStatusCallback_Release(bsc);
572 static void test_BindToStorage(void)
574 IMoniker *mon;
575 HRESULT hres;
576 LPOLESTR display_name;
577 IBindCtx *bctx;
578 MSG msg;
579 IBindStatusCallback *previousclb, *sclb = statusclb_create();
580 IUnknown *unk = (IUnknown*)0x00ff00ff;
581 IBinding *bind;
583 hres = CreateAsyncBindCtx(0, sclb, NULL, &bctx);
584 ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08lx\n\n", hres);
585 if(FAILED(hres)) {
586 IBindStatusCallback_Release(sclb);
587 return;
590 hres = RegisterBindStatusCallback(bctx, sclb, &previousclb, 0);
591 ok(SUCCEEDED(hres), "RegisterBindStatusCallback failed: %08lx\n", hres);
592 ok(previousclb == sclb, "previousclb(%p) != sclb(%p)\n", previousclb, sclb);
593 if(previousclb)
594 IBindStatusCallback_Release(previousclb);
596 hres = CreateURLMoniker(NULL, urls[test_protocol], &mon);
597 ok(SUCCEEDED(hres), "failed to create moniker: %08lx\n", hres);
598 if(FAILED(hres)) {
599 IBindStatusCallback_Release(sclb);
600 IBindCtx_Release(bctx);
601 return;
604 hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
605 ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
606 if(SUCCEEDED(hres))
607 IBinding_Release(bind);
609 hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
610 ok(hres == S_OK, "GetDisplayName failed %08lx\n", hres);
611 ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n");
613 SET_EXPECT(GetBindInfo);
614 SET_EXPECT(OnStartBinding);
615 if(emulate_protocol) {
616 SET_EXPECT(Start);
617 SET_EXPECT(Terminate);
618 SET_EXPECT(UnlockRequest);
619 }else {
620 if(test_protocol == HTTP_TEST) {
621 SET_EXPECT(OnProgress_FINDINGRESOURCE);
622 SET_EXPECT(OnProgress_CONNECTING);
623 SET_EXPECT(OnProgress_SENDINGREQUEST);
625 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
626 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
627 SET_EXPECT(OnDataAvailable);
628 if(test_protocol == HTTP_TEST)
629 SET_EXPECT(OnProgress_DOWNLOADINGDATA);
630 SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
631 SET_EXPECT(OnStopBinding);
634 hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
635 ok(SUCCEEDED(hres), "IMoniker_BindToStorage failed: %08lx\n", hres);
636 if (!SUCCEEDED(hres)) return;
638 if(test_protocol == HTTP_TEST) {
639 todo_wine {
640 ok(unk == NULL, "istr should be NULL\n");
642 }else {
643 ok(unk != NULL, "unk == NULL\n");
645 if(unk)
646 IUnknown_Release(unk);
648 while(!stopped_binding && GetMessage(&msg,NULL,0,0)) {
649 TranslateMessage(&msg);
650 DispatchMessage(&msg);
653 CHECK_CALLED(GetBindInfo);
654 CHECK_CALLED(OnStartBinding);
655 if(emulate_protocol) {
656 CHECK_CALLED(Start);
657 CHECK_CALLED(Terminate);
658 CHECK_CALLED(UnlockRequest);
659 }else {
660 if(test_protocol == HTTP_TEST) {
661 CHECK_CALLED(OnProgress_FINDINGRESOURCE);
662 CHECK_CALLED(OnProgress_CONNECTING);
663 CHECK_CALLED(OnProgress_SENDINGREQUEST);
664 todo_wine { CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); }
665 }else {
666 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
668 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
669 CHECK_CALLED(OnDataAvailable);
670 if(test_protocol == HTTP_TEST)
671 CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
672 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
673 CHECK_CALLED(OnStopBinding);
676 ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
677 ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
678 ok(IBindStatusCallback_Release(sclb) == 0, "scbl should be destroyed here\n");
681 static void test_BindToStorage_fail(void)
683 IMoniker *mon = NULL;
684 IBindCtx *bctx = NULL;
685 IUnknown *unk;
686 HRESULT hres;
688 hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
689 ok(hres == S_OK, "CreateURLMoniker failed: %08lx\n", hres);
690 if(FAILED(hres))
691 return;
693 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
694 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08lx\n", hres);
696 hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
697 ok(hres == INET_E_DATA_NOT_AVAILABLE,
698 "hres=%08lx, expected INET_E_DATA_NOT_AVAILABLE\n", hres);
700 IBindCtx_Release(bctx);
702 IMoniker_Release(mon);
705 START_TEST(url)
707 test_create();
708 test_CreateAsyncBindCtx();
709 test_CreateAsyncBindCtxEx();
711 emulate_protocol = FALSE;
712 test_protocol = HTTP_TEST;
713 test_BindToStorage();
714 test_protocol = ABOUT_TEST;
715 test_BindToStorage();
716 emulate_protocol = TRUE;
717 test_protocol = ABOUT_TEST;
718 test_BindToStorage();
720 test_BindToStorage_fail();