2 * Copyright 2007 Robert Shearman for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #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) \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 expect_ ## func = FALSE; \
42 called_ ## func = TRUE; \
45 #define CHECK_EXPECT2(func) \
47 ok(expect_ ##func, "unexpected call " #func "\n"); \
48 called_ ## func = TRUE; \
51 #define CHECK_CALLED(func) \
53 ok(called_ ## func, "expected " #func "\n"); \
54 expect_ ## func = called_ ## func = FALSE; \
57 #define CHECK_NOT_CALLED(func) \
59 ok(!called_ ## func, "unexpected " #func "\n"); \
60 expect_ ## func = called_ ## func = FALSE; \
63 #define CLEAR_CALLED(func) \
64 expect_ ## func = called_ ## func = FALSE
66 DEFINE_EXPECT(QueryInterface_IServiceProvider
);
67 DEFINE_EXPECT(OnStartBinding
);
68 DEFINE_EXPECT(OnProgress_FINDINGRESOURCE
);
69 DEFINE_EXPECT(OnProgress_CONNECTING
);
70 DEFINE_EXPECT(OnProgress_SENDINGREQUEST
);
71 DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE
);
72 DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA
);
73 DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA
);
74 DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA
);
75 DEFINE_EXPECT(OnStopBinding
);
76 DEFINE_EXPECT(OnDataAvailable
);
77 DEFINE_EXPECT(GetBindInfo
);
79 static const CHAR wszIndexHtmlA
[] = "index.html";
80 static WCHAR INDEX_HTML
[MAX_PATH
];
81 static const char szHtmlDoc
[] = "<HTML></HTML>";
83 static HRESULT WINAPI
statusclb_QueryInterface(IBindStatusCallback
*iface
, REFIID riid
, void **ppv
)
85 if (IsEqualGUID(&IID_IBindStatusCallback
, riid
) ||
86 IsEqualGUID(&IID_IUnknown
, riid
))
91 else if (IsEqualGUID(&IID_IServiceProvider
, riid
))
93 CHECK_EXPECT(QueryInterface_IServiceProvider
);
99 static ULONG WINAPI
statusclb_AddRef(IBindStatusCallback
*iface
)
104 static ULONG WINAPI
statusclb_Release(IBindStatusCallback
*iface
)
109 static HRESULT WINAPI
statusclb_OnStartBinding(IBindStatusCallback
*iface
, DWORD dwReserved
,
115 CHECK_EXPECT(OnStartBinding
);
117 ok(pib
!= NULL
, "pib should not be NULL\n");
119 hres
= IBinding_QueryInterface(pib
, &IID_IMoniker
, (void**)&mon
);
120 ok(hres
== E_NOINTERFACE
, "IBinding should not have IMoniker interface\n");
122 IMoniker_Release(mon
);
127 static HRESULT WINAPI
statusclb_GetPriority(IBindStatusCallback
*iface
, LONG
*pnPriority
)
129 ok(0, "unexpected call\n");
133 static HRESULT WINAPI
statusclb_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
135 ok(0, "unexpected call\n");
139 static HRESULT WINAPI
statusclb_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
140 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
142 switch(ulStatusCode
) {
143 case BINDSTATUS_FINDINGRESOURCE
:
144 CHECK_EXPECT(OnProgress_FINDINGRESOURCE
);
146 case BINDSTATUS_CONNECTING
:
147 CHECK_EXPECT(OnProgress_CONNECTING
);
149 case BINDSTATUS_SENDINGREQUEST
:
150 CHECK_EXPECT(OnProgress_SENDINGREQUEST
);
152 case BINDSTATUS_MIMETYPEAVAILABLE
:
153 CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE
);
155 case BINDSTATUS_BEGINDOWNLOADDATA
:
156 CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA
);
157 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
159 case BINDSTATUS_DOWNLOADINGDATA
:
160 CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA
);
162 case BINDSTATUS_ENDDOWNLOADDATA
:
163 CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA
);
164 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
166 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
167 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
170 todo_wine
{ ok(0, "unexpected code %d\n", ulStatusCode
); }
175 static HRESULT WINAPI
statusclb_OnStopBinding(IBindStatusCallback
*iface
, HRESULT hresult
, LPCWSTR szError
)
177 CHECK_EXPECT(OnStopBinding
);
179 /* ignore DNS failure */
180 if (hresult
!= HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED
))
182 ok(SUCCEEDED(hresult
), "Download failed: %08x\n", hresult
);
183 ok(szError
== NULL
, "szError should be NULL\n");
189 static HRESULT WINAPI
statusclb_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
193 CHECK_EXPECT(GetBindInfo
);
195 *grfBINDF
= BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
| BINDF_PULLDATA
;
196 cbSize
= pbindinfo
->cbSize
;
197 memset(pbindinfo
, 0, cbSize
);
198 pbindinfo
->cbSize
= cbSize
;
203 static HRESULT WINAPI
statusclb_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
204 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
210 CHECK_EXPECT2(OnDataAvailable
);
214 /* FIXME: Uncomment after removing BindToStorage hack. */
215 ok(pformatetc
!= NULL
, "pformatetc == NULL\n");
217 ok(pformatetc
->cfFormat
== 0xc02d, "clipformat=%x\n", pformatetc
->cfFormat
);
218 ok(pformatetc
->ptd
== NULL
, "ptd = %p\n", pformatetc
->ptd
);
219 ok(pformatetc
->dwAspect
== 1, "dwAspect=%u\n", pformatetc
->dwAspect
);
220 ok(pformatetc
->lindex
== -1, "lindex=%d\n", pformatetc
->lindex
);
221 ok(pformatetc
->tymed
== TYMED_ISTREAM
, "tymed=%u\n", pformatetc
->tymed
);
224 ok(pstgmed
!= NULL
, "stgmeg == NULL\n");
226 ok(pstgmed
->tymed
== TYMED_ISTREAM
, "tymed=%u\n", pstgmed
->tymed
);
227 ok(U(*pstgmed
).pstm
!= NULL
, "pstm == NULL\n");
228 ok(pstgmed
->pUnkForRelease
!= NULL
, "pUnkForRelease == NULL\n");
232 if(U(*pstgmed
).pstm
) {
233 do hres
= IStream_Read(U(*pstgmed
).pstm
, buf
, 512, &read
);
235 ok(hres
== S_FALSE
|| hres
== E_PENDING
, "IStream_Read returned %08x\n", hres
);
241 static HRESULT WINAPI
statusclb_OnObjectAvailable(IBindStatusCallback
*iface
, REFIID riid
, IUnknown
*punk
)
243 ok(0, "unexpected call\n");
247 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
248 statusclb_QueryInterface
,
251 statusclb_OnStartBinding
,
252 statusclb_GetPriority
,
253 statusclb_OnLowResource
,
254 statusclb_OnProgress
,
255 statusclb_OnStopBinding
,
256 statusclb_GetBindInfo
,
257 statusclb_OnDataAvailable
,
258 statusclb_OnObjectAvailable
261 static IBindStatusCallback BindStatusCallback
= { &BindStatusCallbackVtbl
};
263 static void set_file_url(char *path
)
265 char INDEX_HTML_A
[MAX_PATH
];
267 lstrcpyA(INDEX_HTML_A
, "file:///");
268 lstrcatA(INDEX_HTML_A
, path
);
269 MultiByteToWideChar(CP_ACP
, 0, INDEX_HTML_A
, -1, INDEX_HTML
, MAX_PATH
);
272 static void create_file(void)
278 file
= CreateFileA(wszIndexHtmlA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
279 FILE_ATTRIBUTE_NORMAL
, NULL
);
280 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
281 if(file
== INVALID_HANDLE_VALUE
)
284 WriteFile(file
, szHtmlDoc
, sizeof(szHtmlDoc
)-1, &size
, NULL
);
287 GetCurrentDirectoryA(MAX_PATH
, path
);
288 lstrcatA(path
, "\\");
289 lstrcatA(path
, wszIndexHtmlA
);
293 static void test_URLOpenBlockingStreamW(void)
296 IStream
*pStream
= NULL
;
299 hr
= URLOpenBlockingStreamW(NULL
, NULL
, &pStream
, 0, &BindStatusCallback
);
300 ok(hr
== E_INVALIDARG
, "URLOpenBlockingStreamW should have failed with E_INVALIDARG instead of 0x%08x\n", hr
);
301 if (0) /* crashes on Win2k */
303 hr
= URLOpenBlockingStreamW(NULL
, INDEX_HTML
, NULL
, 0, &BindStatusCallback
);
304 ok(hr
== E_INVALIDARG
, "URLOpenBlockingStreamW should have failed with E_INVALIDARG instead of 0x%08x\n", hr
);
307 SET_EXPECT(GetBindInfo
);
308 SET_EXPECT(QueryInterface_IServiceProvider
);
309 SET_EXPECT(OnStartBinding
);
310 SET_EXPECT(OnProgress_SENDINGREQUEST
);
311 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE
);
312 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA
);
313 SET_EXPECT(OnProgress_ENDDOWNLOADDATA
);
314 SET_EXPECT(OnStopBinding
);
316 hr
= URLOpenBlockingStreamW(NULL
, INDEX_HTML
, &pStream
, 0, &BindStatusCallback
);
317 ok(hr
== S_OK
, "URLOpenBlockingStreamW failed with error 0x%08x\n", hr
);
319 CHECK_CALLED(GetBindInfo
);
320 todo_wine
CHECK_CALLED(QueryInterface_IServiceProvider
);
321 CHECK_CALLED(OnStartBinding
);
322 CHECK_CALLED(OnProgress_SENDINGREQUEST
);
323 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE
);
324 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA
);
325 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA
);
326 CHECK_CALLED(OnStopBinding
);
328 ok(pStream
!= NULL
, "pStream is NULL\n");
332 hr
= IStream_Read(pStream
, buffer
, sizeof(buffer
), NULL
);
333 ok(hr
== S_OK
, "IStream_Read failed with error 0x%08x\n", hr
);
334 ok(!memcmp(buffer
, szHtmlDoc
, sizeof(szHtmlDoc
)-1), "read data differs from file\n");
336 IStream_Release(pStream
);
339 hr
= URLOpenBlockingStreamW(NULL
, INDEX_HTML
, &pStream
, 0, NULL
);
340 ok(hr
== S_OK
, "URLOpenBlockingStreamW failed with error 0x%08x\n", hr
);
342 ok(pStream
!= NULL
, "pStream is NULL\n");
346 hr
= IStream_Read(pStream
, buffer
, sizeof(buffer
), NULL
);
347 ok(hr
== S_OK
, "IStream_Read failed with error 0x%08x\n", hr
);
348 ok(!memcmp(buffer
, szHtmlDoc
, sizeof(szHtmlDoc
)-1), "read data differs from file\n");
350 IStream_Release(pStream
);
354 static void test_URLOpenStreamW(void)
358 hr
= URLOpenStreamW(NULL
, NULL
, 0, &BindStatusCallback
);
359 ok(hr
== E_INVALIDARG
, "URLOpenStreamW should have failed with E_INVALIDARG instead of 0x%08x\n", hr
);
361 SET_EXPECT(GetBindInfo
);
362 SET_EXPECT(QueryInterface_IServiceProvider
);
363 SET_EXPECT(OnStartBinding
);
364 SET_EXPECT(OnProgress_SENDINGREQUEST
);
365 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE
);
366 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA
);
367 SET_EXPECT(OnProgress_ENDDOWNLOADDATA
);
368 SET_EXPECT(OnDataAvailable
);
369 SET_EXPECT(OnStopBinding
);
371 hr
= URLOpenStreamW(NULL
, INDEX_HTML
, 0, &BindStatusCallback
);
372 ok(hr
== S_OK
, "URLOpenStreamW failed with error 0x%08x\n", hr
);
374 CHECK_CALLED(GetBindInfo
);
375 todo_wine
CHECK_CALLED(QueryInterface_IServiceProvider
);
376 CHECK_CALLED(OnStartBinding
);
377 CHECK_CALLED(OnProgress_SENDINGREQUEST
);
378 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE
);
379 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA
);
380 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA
);
381 CHECK_CALLED(OnDataAvailable
);
382 CHECK_CALLED(OnStopBinding
);
384 hr
= URLOpenStreamW(NULL
, INDEX_HTML
, 0, NULL
);
385 ok(hr
== S_OK
, "URLOpenStreamW failed with error 0x%08x\n", hr
);
390 if(!GetProcAddress(GetModuleHandleA("urlmon.dll"), "CompareSecurityIds")) {
391 win_skip("Too old IE\n");
396 test_URLOpenBlockingStreamW();
397 test_URLOpenStreamW();
398 DeleteFileA(wszIndexHtmlA
);