TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / urlmon / tests / protocol.c
bloba55db964e45ce6334452f17ecb031927cb4e0352
1 /*
2 * Copyright 2005-2011 Jacek Caban 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
19 #define COBJMACROS
20 #define CONST_VTABLE
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "urlmon.h"
30 #include "wininet.h"
32 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
33 static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
34 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
36 #define DEFINE_EXPECT(func) \
37 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
39 #define SET_EXPECT(func) \
40 expect_ ## func = TRUE
42 #define CHECK_EXPECT2(func) \
43 do { \
44 ok(expect_ ##func, "unexpected call " #func "\n"); \
45 called_ ## func = TRUE; \
46 }while(0)
48 #define CHECK_EXPECT(func) \
49 do { \
50 CHECK_EXPECT2(func); \
51 expect_ ## func = FALSE; \
52 }while(0)
54 #define CHECK_CALLED(func) \
55 do { \
56 ok(called_ ## func, "expected " #func "\n"); \
57 expect_ ## func = called_ ## func = FALSE; \
58 }while(0)
60 #define CHECK_NOT_CALLED(func) \
61 do { \
62 ok(!called_ ## func, "unexpected " #func "\n"); \
63 expect_ ## func = called_ ## func = FALSE; \
64 }while(0)
66 #define CLEAR_CALLED(func) \
67 expect_ ## func = called_ ## func = FALSE
69 DEFINE_EXPECT(GetBindInfo);
70 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
71 DEFINE_EXPECT(ReportProgress_DIRECTBIND);
72 DEFINE_EXPECT(ReportProgress_RAWMIMETYPE);
73 DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE);
74 DEFINE_EXPECT(ReportProgress_CONNECTING);
75 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
76 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
77 DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
78 DEFINE_EXPECT(ReportProgress_PROTOCOLCLASSID);
79 DEFINE_EXPECT(ReportProgress_COOKIE_SENT);
80 DEFINE_EXPECT(ReportProgress_REDIRECTING);
81 DEFINE_EXPECT(ReportProgress_ENCODING);
82 DEFINE_EXPECT(ReportProgress_ACCEPTRANGES);
83 DEFINE_EXPECT(ReportProgress_PROXYDETECTING);
84 DEFINE_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
85 DEFINE_EXPECT(ReportProgress_DECODING);
86 DEFINE_EXPECT(ReportData);
87 DEFINE_EXPECT(ReportData2);
88 DEFINE_EXPECT(ReportResult);
89 DEFINE_EXPECT(GetBindString_ACCEPT_MIMES);
90 DEFINE_EXPECT(GetBindString_USER_AGENT);
91 DEFINE_EXPECT(GetBindString_POST_COOKIE);
92 DEFINE_EXPECT(GetBindString_URL);
93 DEFINE_EXPECT(GetBindString_ROOTDOC_URL);
94 DEFINE_EXPECT(QueryService_HttpNegotiate);
95 DEFINE_EXPECT(QueryService_InternetProtocol);
96 DEFINE_EXPECT(QueryService_HttpSecurity);
97 DEFINE_EXPECT(QueryInterface_IWinInetInfo);
98 DEFINE_EXPECT(QueryInterface_IWinInetHttpInfo);
99 DEFINE_EXPECT(BeginningTransaction);
100 DEFINE_EXPECT(GetRootSecurityId);
101 DEFINE_EXPECT(OnResponse);
102 DEFINE_EXPECT(Switch);
103 DEFINE_EXPECT(Continue);
104 DEFINE_EXPECT(CreateInstance);
105 DEFINE_EXPECT(Start);
106 DEFINE_EXPECT(StartEx);
107 DEFINE_EXPECT(Terminate);
108 DEFINE_EXPECT(Read);
109 DEFINE_EXPECT(Read2);
110 DEFINE_EXPECT(SetPriority);
111 DEFINE_EXPECT(LockRequest);
112 DEFINE_EXPECT(UnlockRequest);
113 DEFINE_EXPECT(Abort);
114 DEFINE_EXPECT(MimeFilter_CreateInstance);
115 DEFINE_EXPECT(MimeFilter_Start);
116 DEFINE_EXPECT(MimeFilter_ReportData);
117 DEFINE_EXPECT(MimeFilter_ReportResult);
118 DEFINE_EXPECT(MimeFilter_Terminate);
119 DEFINE_EXPECT(MimeFilter_LockRequest);
120 DEFINE_EXPECT(MimeFilter_UnlockRequest);
121 DEFINE_EXPECT(MimeFilter_Read);
122 DEFINE_EXPECT(MimeFilter_Switch);
123 DEFINE_EXPECT(MimeFilter_Continue);
124 DEFINE_EXPECT(Stream_Seek);
125 DEFINE_EXPECT(Stream_Read);
127 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
128 static const WCHAR index_url[] =
129 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
131 static const WCHAR acc_mimeW[] = {'*','/','*',0};
132 static const WCHAR user_agentW[] = {'W','i','n','e',0};
133 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
134 static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
135 static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
136 static const WCHAR emptyW[] = {0};
137 static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
138 static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0};
140 static HRESULT expect_hrResult;
141 static LPCWSTR file_name, http_url, expect_wsz;
142 static IInternetProtocol *async_protocol = NULL;
143 static BOOL first_data_notif, http_is_first, test_redirect;
144 static int prot_state, read_report_data, post_stream_read;
145 static DWORD bindf, ex_priority , pi;
146 static IInternetProtocol *binding_protocol, *filtered_protocol;
147 static IInternetBindInfo *prot_bind_info;
148 static IInternetProtocolSink *binding_sink, *filtered_sink;
149 static void *expect_pv;
150 static HANDLE event_complete, event_complete2, event_continue, event_continue_done;
151 static BOOL binding_test;
152 static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
153 static DWORD prot_read, filter_state, http_post_test, thread_id;
154 static BOOL security_problem, test_async_req, impl_protex;
155 static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort;
156 static BOOL empty_file, no_mime, bind_from_cache, file_with_hash;
158 enum {
159 STATE_CONNECTING,
160 STATE_SENDINGREQUEST,
161 STATE_STARTDOWNLOADING,
162 STATE_DOWNLOADING
163 } state;
165 static enum {
166 FILE_TEST,
167 HTTP_TEST,
168 HTTPS_TEST,
169 FTP_TEST,
170 MK_TEST,
171 ITS_TEST,
172 BIND_TEST
173 } tested_protocol;
175 static const WCHAR protocol_names[][10] = {
176 {'f','i','l','e',0},
177 {'h','t','t','p',0},
178 {'h','t','t','p','s',0},
179 {'f','t','p',0},
180 {'m','k',0},
181 {'i','t','s',0},
182 {'t','e','s','t',0}
185 static const WCHAR binding_urls[][130] = {
186 {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
187 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
188 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0},
189 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
190 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
191 {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
192 '/','p','u','b','/','o','t','h','e','r',
193 '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
194 {'m','k',':','t','e','s','t',0},
195 {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0},
196 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
199 static const CHAR post_data[] = "mode=Test";
201 static int strcmp_wa(LPCWSTR strw, const char *stra)
203 CHAR buf[512];
204 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
205 return lstrcmpA(stra, buf);
208 static const char *w2a(LPCWSTR str)
210 static char buf[INTERNET_MAX_URL_LENGTH];
211 WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
212 return buf;
215 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
217 if(IsEqualGUID(&IID_IUnknown, riid)
218 || IsEqualGUID(&IID_IHttpSecurity, riid)) {
219 *ppv = iface;
220 return S_OK;
223 ok(0, "unexpected call\n");
224 return E_NOINTERFACE;
227 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
229 return 2;
232 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
234 return 1;
237 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
239 trace("HttpSecurity_GetWindow\n");
241 return S_FALSE;
244 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
246 trace("Security problem: %u\n", dwProblem);
247 ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED, "Expected ERROR_INTERNET_SEC_CERT_REV_FAILED got %u\n", dwProblem);
249 /* Only retry once */
250 if (security_problem)
251 return E_ABORT;
253 security_problem = TRUE;
254 SET_EXPECT(BeginningTransaction);
256 return RPC_E_RETRY;
259 static IHttpSecurityVtbl HttpSecurityVtbl = {
260 HttpSecurity_QueryInterface,
261 HttpSecurity_AddRef,
262 HttpSecurity_Release,
263 HttpSecurity_GetWindow,
264 HttpSecurity_OnSecurityProblem
267 static IHttpSecurity http_security = { &HttpSecurityVtbl };
269 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
271 if(IsEqualGUID(&IID_IUnknown, riid)
272 || IsEqualGUID(&IID_IHttpNegotiate, riid)
273 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
274 *ppv = iface;
275 return S_OK;
278 ok(0, "unexpected call\n");
279 return E_NOINTERFACE;
282 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
284 return 2;
287 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
289 return 1;
292 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
293 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
295 LPWSTR addl_headers;
297 static const WCHAR wszHeaders[] =
298 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
299 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
300 'd','e','d','\r','\n',0};
302 CHECK_EXPECT(BeginningTransaction);
304 if(binding_test)
305 ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
306 else
307 ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
308 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
309 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
310 if(pszAdditionalHeaders)
312 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
313 if (http_post_test)
315 addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
316 memcpy(addl_headers, wszHeaders, sizeof(wszHeaders));
317 *pszAdditionalHeaders = addl_headers;
321 return S_OK;
324 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
325 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
327 CHECK_EXPECT(OnResponse);
329 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
330 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
331 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
332 ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
334 return S_OK;
337 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
338 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
340 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
342 CHECK_EXPECT(GetRootSecurityId);
344 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
345 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
346 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
348 if(pcbSecurityId) {
349 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
350 *pcbSecurityId = sizeof(sec_id);
353 if(pbSecurityId)
354 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
356 return E_FAIL;
359 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
360 HttpNegotiate_QueryInterface,
361 HttpNegotiate_AddRef,
362 HttpNegotiate_Release,
363 HttpNegotiate_BeginningTransaction,
364 HttpNegotiate_OnResponse,
365 HttpNegotiate_GetRootSecurityId
368 static IHttpNegotiate2 http_negotiate = { &HttpNegotiateVtbl };
370 static HRESULT QueryInterface(REFIID,void**);
372 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
374 return QueryInterface(riid, ppv);
377 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
379 return 2;
382 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
384 return 1;
387 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
388 REFIID riid, void **ppv)
390 if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
391 CHECK_EXPECT2(QueryService_HttpNegotiate);
392 return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
395 if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
396 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
397 CHECK_EXPECT(QueryService_InternetProtocol);
398 return E_NOINTERFACE;
401 if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
402 ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
403 CHECK_EXPECT(QueryService_HttpSecurity);
404 return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
407 if(IsEqualGUID(&IID_IGetBindHandle, guidService)) {
408 trace("QueryService(IID_IGetBindHandle)\n");
409 *ppv = NULL;
410 return E_NOINTERFACE;
413 if(IsEqualGUID(&IID_IWindowForBindingUI, guidService)) {
414 trace("QueryService(IID_IWindowForBindingUI)\n");
415 *ppv = NULL;
416 return E_NOINTERFACE;
419 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
420 return E_FAIL;
423 static const IServiceProviderVtbl ServiceProviderVtbl = {
424 ServiceProvider_QueryInterface,
425 ServiceProvider_AddRef,
426 ServiceProvider_Release,
427 ServiceProvider_QueryService
430 static IServiceProvider service_provider = { &ServiceProviderVtbl };
432 static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
434 static const IID IID_strm_unknown = {0x2f68429a,0x199a,0x4043,{0x93,0x11,0xf2,0xfe,0x7c,0x13,0xcc,0xb9}};
436 if(!IsEqualGUID(&IID_strm_unknown, riid)) /* IE11 */
437 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
439 *ppv = NULL;
440 return E_NOINTERFACE;
443 static ULONG WINAPI Stream_AddRef(IStream *iface)
445 return 2;
448 static ULONG WINAPI Stream_Release(IStream *iface)
450 return 1;
453 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
454 ULONG cb, ULONG *pcbRead)
456 CHECK_EXPECT2(Stream_Read);
458 ok(GetCurrentThreadId() != thread_id, "wrong thread %d\n", GetCurrentThreadId());
460 ok(pv != NULL, "pv == NULL\n");
461 ok(cb == 0x20000 || broken(cb == 0x2000), "cb = %d\n", cb);
462 ok(pcbRead != NULL, "pcbRead == NULL\n");
464 if(post_stream_read) {
465 *pcbRead = 0;
466 return S_FALSE;
469 memcpy(pv, post_data, sizeof(post_data)-1);
470 post_stream_read += *pcbRead = sizeof(post_data)-1;
471 return S_OK;
474 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
475 ULONG cb, ULONG *pcbWritten)
477 ok(0, "unexpected call\n");
478 return E_NOTIMPL;
481 static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
482 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
484 CHECK_EXPECT(Stream_Seek);
486 ok(!dlibMove.QuadPart, "dlibMove != 0\n");
487 ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
488 ok(!plibNewPosition, "plibNewPosition == NULL\n");
490 return S_OK;
493 static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
495 ok(0, "unexpected call\n");
496 return E_NOTIMPL;
499 static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm,
500 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
502 ok(0, "unexpected call\n");
503 return E_NOTIMPL;
506 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
508 ok(0, "unexpected call\n");
509 return E_NOTIMPL;
512 static HRESULT WINAPI Stream_Revert(IStream *iface)
514 ok(0, "unexpected call\n");
515 return E_NOTIMPL;
518 static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
519 ULARGE_INTEGER cb, DWORD dwLockType)
521 ok(0, "unexpected call\n");
522 return E_NOTIMPL;
525 static HRESULT WINAPI Stream_UnlockRegion(IStream *iface,
526 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
528 ok(0, "unexpected call\n");
529 return E_NOTIMPL;
532 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
533 DWORD dwStatFlag)
535 ok(0, "unexpected call\n");
536 return E_NOTIMPL;
539 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
541 ok(0, "unexpected call\n");
542 return E_NOTIMPL;
545 static const IStreamVtbl StreamVtbl = {
546 Stream_QueryInterface,
547 Stream_AddRef,
548 Stream_Release,
549 Stream_Read,
550 Stream_Write,
551 Stream_Seek,
552 Stream_SetSize,
553 Stream_CopyTo,
554 Stream_Commit,
555 Stream_Revert,
556 Stream_LockRegion,
557 Stream_UnlockRegion,
558 Stream_Stat,
559 Stream_Clone
562 static IStream Stream = { &StreamVtbl };
564 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
566 return QueryInterface(riid, ppv);
569 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
571 return 2;
574 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
576 return 1;
579 static void call_continue(PROTOCOLDATA *protocol_data)
581 HRESULT hres;
583 if (winetest_debug > 1)
584 trace("continue in state %d\n", state);
586 if(state == STATE_CONNECTING) {
587 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
588 if (http_is_first){
589 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
590 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
592 CLEAR_CALLED(ReportProgress_CONNECTING);
594 if(tested_protocol == FTP_TEST)
595 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
596 else if (tested_protocol != HTTPS_TEST)
597 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
598 if(test_redirect)
599 CHECK_CALLED(ReportProgress_REDIRECTING);
600 state = test_async_req ? STATE_SENDINGREQUEST : STATE_STARTDOWNLOADING;
603 switch(state) {
604 case STATE_SENDINGREQUEST:
605 SET_EXPECT(Stream_Read);
606 SET_EXPECT(ReportProgress_SENDINGREQUEST);
607 break;
608 case STATE_STARTDOWNLOADING:
609 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
610 SET_EXPECT(OnResponse);
611 if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file)
612 SET_EXPECT(ReportProgress_ACCEPTRANGES);
613 SET_EXPECT(ReportProgress_ENCODING);
614 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
615 if(bindf & BINDF_NEEDFILE)
616 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
618 default:
619 break;
622 if(state != STATE_SENDINGREQUEST)
623 SET_EXPECT(ReportData);
624 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
625 ok(hres == S_OK, "Continue failed: %08x\n", hres);
626 if(tested_protocol == FTP_TEST || security_problem)
627 CLEAR_CALLED(ReportData);
628 else if(state != STATE_SENDINGREQUEST)
629 CHECK_CALLED(ReportData);
631 switch(state) {
632 case STATE_SENDINGREQUEST:
633 CHECK_CALLED(Stream_Read);
634 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
635 state = STATE_STARTDOWNLOADING;
636 break;
637 case STATE_STARTDOWNLOADING:
638 if (! security_problem)
640 state = STATE_DOWNLOADING;
641 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
642 CHECK_CALLED(OnResponse);
643 if(tested_protocol == HTTPS_TEST || empty_file)
644 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
645 else if(test_redirect || test_abort)
646 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
647 CLEAR_CALLED(ReportProgress_ENCODING);
648 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
649 if(bindf & BINDF_NEEDFILE)
650 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
653 else
655 security_problem = FALSE;
656 SET_EXPECT(ReportProgress_CONNECTING);
658 default:
659 break;
663 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
665 if(tested_protocol == FTP_TEST)
666 CHECK_EXPECT2(Switch);
667 else
668 CHECK_EXPECT(Switch);
670 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
671 if(binding_test) {
672 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
673 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
674 pProtocolData->grfFlags, protocoldata.grfFlags );
675 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
676 pProtocolData->dwState, protocoldata.dwState );
677 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
678 pProtocolData->pData, protocoldata.pData );
679 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
680 pProtocolData->cbData, protocoldata.cbData );
683 pdata = pProtocolData;
685 if(binding_test) {
686 SetEvent(event_complete);
687 ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
688 return S_OK;
689 }if(direct_read) {
690 continue_protdata = *pProtocolData;
691 SetEvent(event_continue);
692 ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
693 }else {
694 call_continue(pProtocolData);
695 SetEvent(event_complete);
698 return S_OK;
701 static const char *status_names[] =
703 "0",
704 "FINDINGRESOURCE",
705 "CONNECTING",
706 "REDIRECTING",
707 "BEGINDOWNLOADDATA",
708 "DOWNLOADINGDATA",
709 "ENDDOWNLOADDATA",
710 "BEGINDOWNLOADCOMPONENTS",
711 "INSTALLINGCOMPONENTS",
712 "ENDDOWNLOADCOMPONENTS",
713 "USINGCACHEDCOPY",
714 "SENDINGREQUEST",
715 "CLASSIDAVAILABLE",
716 "MIMETYPEAVAILABLE",
717 "CACHEFILENAMEAVAILABLE",
718 "BEGINSYNCOPERATION",
719 "ENDSYNCOPERATION",
720 "BEGINUPLOADDATA",
721 "UPLOADINGDATA",
722 "ENDUPLOADINGDATA",
723 "PROTOCOLCLASSID",
724 "ENCODING",
725 "VERIFIEDMIMETYPEAVAILABLE",
726 "CLASSINSTALLLOCATION",
727 "DECODING",
728 "LOADINGMIMEHANDLER",
729 "CONTENTDISPOSITIONATTACH",
730 "FILTERREPORTMIMETYPE",
731 "CLSIDCANINSTANTIATE",
732 "IUNKNOWNAVAILABLE",
733 "DIRECTBIND",
734 "RAWMIMETYPE",
735 "PROXYDETECTING",
736 "ACCEPTRANGES",
737 "COOKIE_SENT",
738 "COMPACT_POLICY_RECEIVED",
739 "COOKIE_SUPPRESSED",
740 "COOKIE_STATE_UNKNOWN",
741 "COOKIE_STATE_ACCEPT",
742 "COOKIE_STATE_REJECT",
743 "COOKIE_STATE_PROMPT",
744 "COOKIE_STATE_LEASH",
745 "COOKIE_STATE_DOWNGRADE",
746 "POLICY_HREF",
747 "P3P_HEADER",
748 "SESSION_COOKIE_RECEIVED",
749 "PERSISTENT_COOKIE_RECEIVED",
750 "SESSION_COOKIES_ALLOWED",
751 "CACHECONTROL",
752 "CONTENTDISPOSITIONFILENAME",
753 "MIMETEXTPLAINMISMATCH",
754 "PUBLISHERAVAILABLE",
755 "DISPLAYNAMEAVAILABLE"
758 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
759 LPCWSTR szStatusText)
761 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
762 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
763 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
765 if (winetest_debug > 1)
767 if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0]))
768 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
769 else
770 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
773 switch(ulStatusCode) {
774 case BINDSTATUS_MIMETYPEAVAILABLE:
775 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
776 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
777 if(!short_read || !direct_read)
778 CHECK_CALLED(Read); /* set in Continue */
779 else if(short_read)
780 CHECK_CALLED(Read2); /* set in Read */
782 ok(szStatusText != NULL, "szStatusText == NULL\n");
783 if(szStatusText) {
784 if(tested_protocol == BIND_TEST)
785 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
786 else if (http_post_test)
787 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
788 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
789 "szStatusText != text/plain\n");
790 else if(empty_file)
791 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
792 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
793 && tested_protocol==HTTP_TEST && !short_read)
794 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
795 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
796 "szStatusText != image/gif\n");
797 else if(!mimefilter_test)
798 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
799 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
800 "szStatusText != text/html\n");
802 break;
803 case BINDSTATUS_DIRECTBIND:
804 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
805 ok(szStatusText == NULL, "szStatusText != NULL\n");
806 break;
807 case BINDSTATUS_RAWMIMETYPE:
808 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
809 ok(szStatusText != NULL, "szStatusText == NULL\n");
810 if(szStatusText)
811 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
812 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
813 "szStatusText != text/html\n");
814 break;
815 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
816 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
817 ok(szStatusText != NULL, "szStatusText == NULL\n");
818 if(szStatusText) {
819 if(binding_test)
820 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
821 else if(tested_protocol == FILE_TEST)
822 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
823 else
824 ok(szStatusText != NULL, "szStatusText == NULL\n");
826 break;
827 case BINDSTATUS_FINDINGRESOURCE:
828 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
829 ok(szStatusText != NULL, "szStatusText == NULL\n");
830 break;
831 case BINDSTATUS_CONNECTING:
832 CHECK_EXPECT2(ReportProgress_CONNECTING);
833 ok(szStatusText != NULL, "szStatusText == NULL\n");
834 break;
835 case BINDSTATUS_SENDINGREQUEST:
836 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
837 if(tested_protocol == FILE_TEST || tested_protocol == ITS_TEST) {
838 ok(szStatusText != NULL, "szStatusText == NULL\n");
839 if(szStatusText)
840 ok(!*szStatusText, "wrong szStatusText\n");
842 break;
843 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
844 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
845 ok(szStatusText != NULL, "szStatusText == NULL\n");
846 if(szStatusText)
847 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
848 break;
849 case BINDSTATUS_PROTOCOLCLASSID:
850 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
851 ok(szStatusText != NULL, "szStatusText == NULL\n");
852 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
853 break;
854 case BINDSTATUS_COOKIE_SENT:
855 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
856 ok(szStatusText == NULL, "szStatusText != NULL\n");
857 break;
858 case BINDSTATUS_REDIRECTING:
859 CHECK_EXPECT(ReportProgress_REDIRECTING);
860 if(test_redirect)
861 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
862 else
863 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
864 break;
865 case BINDSTATUS_ENCODING:
866 CHECK_EXPECT(ReportProgress_ENCODING);
867 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
868 break;
869 case BINDSTATUS_ACCEPTRANGES:
870 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
871 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
872 break;
873 case BINDSTATUS_PROXYDETECTING:
874 if(!called_ReportProgress_PROXYDETECTING)
875 SET_EXPECT(ReportProgress_CONNECTING);
876 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
877 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
878 break;
879 case BINDSTATUS_LOADINGMIMEHANDLER:
880 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
881 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
882 break;
883 case BINDSTATUS_DECODING:
884 CHECK_EXPECT(ReportProgress_DECODING);
885 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
886 break;
887 case BINDSTATUS_RESERVED_7:
888 trace("BINDSTATUS_RESERVED_7\n");
889 break;
890 case BINDSTATUS_RESERVED_8:
891 trace("BINDSTATUS_RESERVED_8\n");
892 break;
893 default:
894 ok(0, "Unexpected status %d (%d)\n", ulStatusCode, ulStatusCode-BINDSTATUS_LAST);
897 return S_OK;
900 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
901 ULONG ulProgress, ULONG ulProgressMax)
903 HRESULT hres;
905 static int rec_depth;
906 rec_depth++;
908 if(!mimefilter_test && (tested_protocol == FILE_TEST || tested_protocol == ITS_TEST)) {
909 CHECK_EXPECT2(ReportData);
911 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
912 ulProgress, ulProgressMax);
913 if(!file_with_hash)
914 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
915 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
916 if(tested_protocol == FILE_TEST)
917 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
918 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
919 "grcfBSCF = %08x\n", grfBSCF);
920 else
921 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
922 }else if(bind_from_cache) {
923 CHECK_EXPECT(ReportData);
925 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
926 ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
927 ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
928 }else if(direct_read) {
929 BYTE buf[14096];
930 ULONG read;
932 if(!read_report_data && rec_depth == 1) {
933 BOOL reported_all_data = called_ReportData2;
935 CHECK_EXPECT2(ReportData);
937 if(short_read) {
938 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
939 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
940 "grcfBSCF = %08x\n", grfBSCF);
941 CHECK_CALLED(Read); /* Set in Continue */
942 first_data_notif = FALSE;
943 }else if(first_data_notif) {
944 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
945 first_data_notif = FALSE;
946 }else if(reported_all_data) {
947 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
948 "grcfBSCF = %08x\n", grfBSCF);
949 }else if(!direct_read) {
950 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
953 do {
954 read = 0;
955 if(emulate_prot)
956 SET_EXPECT(Read);
957 else
958 SET_EXPECT(ReportData2);
959 SET_EXPECT(ReportResult);
960 if(!emulate_prot)
961 SET_EXPECT(Switch);
962 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
963 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
964 if(hres == S_OK)
965 ok(read, "read == 0\n");
966 if(reported_all_data)
967 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
968 if(!emulate_prot && hres != E_PENDING)
969 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
970 if(emulate_prot)
971 CHECK_CALLED(Read);
972 if(!reported_all_data && called_ReportData2) {
973 if(!emulate_prot)
974 CHECK_CALLED(ReportData2);
975 CHECK_CALLED(ReportResult);
976 reported_all_data = TRUE;
977 }else {
978 if(!emulate_prot)
979 CHECK_NOT_CALLED(ReportData2);
980 CHECK_NOT_CALLED(ReportResult);
982 }while(hres == S_OK);
983 if(hres == S_FALSE)
984 wait_for_switch = FALSE;
985 }else {
986 CHECK_EXPECT(ReportData2);
988 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
990 read = 0xdeadbeef;
991 if(emulate_prot)
992 SET_EXPECT(Read2);
993 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
994 if(emulate_prot)
995 CHECK_CALLED(Read2);
996 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
997 ok(!read, "read = %d\n", read);
999 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST
1000 || tested_protocol == FTP_TEST)) {
1001 if(empty_file)
1002 CHECK_EXPECT2(ReportData);
1003 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
1004 CHECK_EXPECT(ReportData);
1005 else if (http_post_test)
1006 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
1008 if(empty_file) {
1009 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
1010 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
1011 }else {
1012 ok(ulProgress, "ulProgress == 0\n");
1015 if(empty_file) {
1016 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
1017 "grcfBSCF = %08x\n", grfBSCF);
1018 first_data_notif = FALSE;
1019 }else if(first_data_notif) {
1020 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1021 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1022 "grcfBSCF = %08x\n", grfBSCF);
1023 first_data_notif = FALSE;
1024 } else {
1025 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1026 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1027 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1028 "grcfBSCF = %08x\n", grfBSCF);
1031 if(!(bindf & BINDF_FROMURLMON) &&
1032 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1033 if(state == STATE_CONNECTING) {
1034 state = STATE_DOWNLOADING;
1035 if(http_is_first) {
1036 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1037 CHECK_CALLED(ReportProgress_CONNECTING);
1039 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1040 CHECK_CALLED(OnResponse);
1041 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1043 SetEvent(event_complete);
1045 }else if(!read_report_data) {
1046 BYTE buf[1000];
1047 ULONG read;
1048 HRESULT hres;
1050 CHECK_EXPECT(ReportData);
1052 if(tested_protocol != BIND_TEST) {
1053 do {
1054 if(mimefilter_test)
1055 SET_EXPECT(MimeFilter_Read);
1056 else if(rec_depth > 1)
1057 SET_EXPECT(Read2);
1058 else
1059 SET_EXPECT(Read);
1060 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1061 if(mimefilter_test)
1062 CHECK_CALLED(MimeFilter_Read);
1063 else if(rec_depth > 1)
1064 CHECK_CALLED(Read2);
1065 else
1066 CHECK_CALLED(Read);
1067 }while(hres == S_OK);
1071 rec_depth--;
1072 return S_OK;
1075 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1076 DWORD dwError, LPCWSTR szResult)
1078 CHECK_EXPECT(ReportResult);
1080 if(tested_protocol == FTP_TEST)
1081 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1082 else
1083 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1084 hrResult, expect_hrResult);
1085 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort)
1086 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1087 else
1088 ok(dwError != ERROR_SUCCESS ||
1089 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1090 "dwError == ERROR_SUCCESS\n");
1091 ok(!szResult, "szResult != NULL\n");
1093 if(direct_read)
1094 SET_EXPECT(ReportData); /* checked after main loop */
1096 return S_OK;
1099 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1100 ProtocolSink_QueryInterface,
1101 ProtocolSink_AddRef,
1102 ProtocolSink_Release,
1103 ProtocolSink_Switch,
1104 ProtocolSink_ReportProgress,
1105 ProtocolSink_ReportData,
1106 ProtocolSink_ReportResult
1109 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
1111 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
1113 ok(0, "unexpected call\n");
1114 return E_NOTIMPL;
1117 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1119 return 2;
1122 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1124 return 1;
1127 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1129 HRESULT hres;
1131 CHECK_EXPECT(MimeFilter_Switch);
1133 SET_EXPECT(Switch);
1134 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1135 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1136 CHECK_CALLED(Switch);
1138 return S_OK;
1141 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1142 LPCWSTR szStatusText)
1144 switch(ulStatusCode) {
1145 case BINDSTATUS_LOADINGMIMEHANDLER:
1147 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1148 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1149 * ProtocolSink_ReportProgress to workaround it.
1151 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1152 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1153 break;
1154 default:
1155 ok(0, "Unexpected status code %d\n", ulStatusCode);
1158 return S_OK;
1161 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1162 ULONG ulProgress, ULONG ulProgressMax)
1164 DWORD read = 0;
1165 BYTE buf[8192];
1166 HRESULT hres;
1167 BOOL report_mime = FALSE;
1169 CHECK_EXPECT(MimeFilter_ReportData);
1171 if(!filter_state && !no_mime) {
1172 SET_EXPECT(Read);
1173 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1174 if(tested_protocol == HTTP_TEST)
1175 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1176 else
1177 ok(hres == S_OK, "Read failed: %08x\n", hres);
1178 CHECK_CALLED(Read);
1180 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1181 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1182 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1183 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1185 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1186 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1187 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1188 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1190 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1193 if(no_mime && prot_read<200) {
1194 SET_EXPECT(Read);
1195 }else if(no_mime && prot_read<300) {
1196 report_mime = TRUE;
1197 SET_EXPECT(Read);
1198 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1199 SET_EXPECT(ReportData);
1200 }else if(!read_report_data) {
1201 SET_EXPECT(ReportData);
1203 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1204 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1205 if(no_mime && prot_read<=200) {
1206 CHECK_CALLED(Read);
1207 }else if(report_mime) {
1208 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1209 CHECK_CALLED(ReportData);
1210 }else if(!read_report_data) {
1211 CHECK_CALLED(ReportData);
1214 if(!filter_state)
1215 filter_state = 1;
1217 return S_OK;
1220 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1221 DWORD dwError, LPCWSTR szResult)
1223 HRESULT hres;
1225 CHECK_EXPECT(MimeFilter_ReportResult);
1227 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1228 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1229 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1231 SET_EXPECT(ReportResult);
1232 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1233 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1234 CHECK_CALLED(ReportResult);
1236 return S_OK;
1239 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1240 MimeProtocolSink_QueryInterface,
1241 MimeProtocolSink_AddRef,
1242 MimeProtocolSink_Release,
1243 MimeProtocolSink_Switch,
1244 MimeProtocolSink_ReportProgress,
1245 MimeProtocolSink_ReportData,
1246 MimeProtocolSink_ReportResult
1249 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1251 static HRESULT QueryInterface(REFIID riid, void **ppv)
1253 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1254 static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1256 *ppv = NULL;
1258 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1259 *ppv = &protocol_sink;
1260 if(IsEqualGUID(&IID_IServiceProvider, riid))
1261 *ppv = &service_provider;
1262 if(IsEqualGUID(&IID_IUriContainer, riid))
1263 return E_NOINTERFACE; /* TODO */
1265 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1266 if(IsEqualGUID(&IID_undocumented, riid))
1267 return E_NOINTERFACE;
1268 /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1269 if(IsEqualGUID(&IID_undocumentedIE10, riid))
1270 return E_NOINTERFACE;
1272 if(*ppv)
1273 return S_OK;
1275 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1276 return E_NOINTERFACE;
1279 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1281 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1282 *ppv = iface;
1283 return S_OK;
1285 return E_NOINTERFACE;
1288 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1290 return 2;
1293 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1295 return 1;
1298 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1300 DWORD cbSize;
1302 CHECK_EXPECT(GetBindInfo);
1304 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1305 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1306 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1308 *grfBINDF = bindf;
1309 if(binding_test)
1310 *grfBINDF |= BINDF_FROMURLMON;
1311 cbSize = pbindinfo->cbSize;
1312 memset(pbindinfo, 0, cbSize);
1313 pbindinfo->cbSize = cbSize;
1315 if(http_post_test)
1317 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1318 pbindinfo->dwBindVerb = BINDVERB_POST;
1319 pbindinfo->stgmedData.tymed = http_post_test;
1321 if(http_post_test == TYMED_HGLOBAL) {
1322 HGLOBAL data;
1324 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1325 data = GlobalAlloc(GPTR, sizeof(post_data));
1326 memcpy(data, post_data, sizeof(post_data));
1327 U(pbindinfo->stgmedData).hGlobal = data;
1328 }else {
1329 IStream *post_stream;
1330 HGLOBAL data;
1331 HRESULT hres;
1333 if(0) {
1334 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1335 data = GlobalAlloc(GPTR, sizeof(post_data));
1336 memcpy(data, post_data, sizeof(post_data));
1337 U(pbindinfo->stgmedData).hGlobal = data;
1339 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1340 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1342 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1344 U(pbindinfo->stgmedData).pstm = &Stream;
1348 return S_OK;
1351 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1352 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1354 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1355 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1357 switch(ulStringType) {
1358 case BINDSTRING_ACCEPT_MIMES:
1359 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1360 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1361 if(pcElFetched) {
1362 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1363 *pcElFetched = 1;
1365 if(ppwzStr) {
1366 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1367 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1369 return S_OK;
1370 case BINDSTRING_USER_AGENT:
1371 CHECK_EXPECT(GetBindString_USER_AGENT);
1372 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1373 if(pcElFetched) {
1374 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1375 *pcElFetched = 1;
1377 if(ppwzStr) {
1378 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1379 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1381 return S_OK;
1382 case BINDSTRING_POST_COOKIE:
1383 CHECK_EXPECT(GetBindString_POST_COOKIE);
1384 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1385 if(pcElFetched)
1386 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1387 return S_OK;
1388 case BINDSTRING_URL: {
1389 DWORD size;
1391 CHECK_EXPECT(GetBindString_URL);
1392 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1393 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1394 *pcElFetched = 1;
1396 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1397 *ppwzStr = CoTaskMemAlloc(size);
1398 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1399 return S_OK;
1401 case BINDSTRING_ROOTDOC_URL:
1402 CHECK_EXPECT(GetBindString_ROOTDOC_URL);
1403 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1404 return E_NOTIMPL;
1405 case BINDSTRING_ENTERPRISE_ID:
1406 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1407 return E_NOTIMPL;
1408 default:
1409 ok(0, "unexpected ulStringType %d\n", ulStringType);
1412 return E_NOTIMPL;
1415 static IInternetBindInfoVtbl bind_info_vtbl = {
1416 BindInfo_QueryInterface,
1417 BindInfo_AddRef,
1418 BindInfo_Release,
1419 BindInfo_GetBindInfo,
1420 BindInfo_GetBindString
1423 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1425 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1426 REFIID riid, void **ppv)
1428 ok(0, "unexpected call\n");
1429 return E_NOINTERFACE;
1432 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1434 return 2;
1437 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1439 return 1;
1442 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1444 CHECK_EXPECT(SetPriority);
1445 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1446 return S_OK;
1449 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1451 ok(0, "unexpected call\n");
1452 return E_NOTIMPL;
1456 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1457 InternetPriority_QueryInterface,
1458 InternetPriority_AddRef,
1459 InternetPriority_Release,
1460 InternetPriority_SetPriority,
1461 InternetPriority_GetPriority
1464 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1466 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1468 return 2;
1471 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1473 return 1;
1476 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1477 DWORD dwOptions)
1479 HRESULT hres;
1481 CHECK_EXPECT(Abort);
1483 SET_EXPECT(ReportResult);
1484 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1485 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1486 CHECK_CALLED(ReportResult);
1488 return S_OK;
1491 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1493 ok(0, "unexpected call\n");
1494 return E_NOTIMPL;
1497 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1499 ok(0, "unexpected call\n");
1500 return E_NOTIMPL;
1503 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1504 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1506 ok(0, "unexpected call\n");
1507 return E_NOTIMPL;
1510 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1512 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1514 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1515 *ppv = iface;
1516 return S_OK;
1519 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1520 if(impl_protex) {
1521 *ppv = iface;
1522 return S_OK;
1524 *ppv = NULL;
1525 return E_NOINTERFACE;
1528 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1529 *ppv = &InternetPriority;
1530 return S_OK;
1533 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1534 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1535 *ppv = NULL;
1536 return E_NOINTERFACE;
1539 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1540 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1541 *ppv = NULL;
1542 return E_NOINTERFACE;
1545 if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */
1546 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1547 *ppv = NULL;
1548 return E_NOINTERFACE;
1551 static DWORD WINAPI thread_proc(PVOID arg)
1553 HRESULT hres;
1555 memset(&protocoldata, -1, sizeof(protocoldata));
1557 prot_state = 0;
1559 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1560 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1561 BINDSTATUS_FINDINGRESOURCE, hostW);
1562 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1563 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1565 SET_EXPECT(ReportProgress_CONNECTING);
1566 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1567 BINDSTATUS_CONNECTING, winehq_ipW);
1568 CHECK_CALLED(ReportProgress_CONNECTING);
1569 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1571 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1572 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1573 BINDSTATUS_SENDINGREQUEST, NULL);
1574 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1575 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1577 prot_state = 1;
1578 SET_EXPECT(Switch);
1579 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1580 CHECK_CALLED(Switch);
1581 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1583 if(!short_read) {
1584 prot_state = 2;
1585 if(mimefilter_test)
1586 SET_EXPECT(MimeFilter_Switch);
1587 else
1588 SET_EXPECT(Switch);
1589 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1590 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1591 if(mimefilter_test)
1592 CHECK_CALLED(MimeFilter_Switch);
1593 else
1594 CHECK_CALLED(Switch);
1596 if(test_abort) {
1597 SetEvent(event_complete);
1598 return 0;
1601 prot_state = 2;
1602 if(mimefilter_test)
1603 SET_EXPECT(MimeFilter_Switch);
1604 else
1605 SET_EXPECT(Switch);
1606 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1607 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1608 if(mimefilter_test)
1609 CHECK_CALLED(MimeFilter_Switch);
1610 else
1611 CHECK_CALLED(Switch);
1613 prot_state = 3;
1614 if(mimefilter_test)
1615 SET_EXPECT(MimeFilter_Switch);
1616 else
1617 SET_EXPECT(Switch);
1618 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1619 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1620 if(mimefilter_test)
1621 CHECK_CALLED(MimeFilter_Switch);
1622 else
1623 CHECK_CALLED(Switch);
1626 SetEvent(event_complete);
1628 return 0;
1631 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1633 BINDINFO bindinfo, exp_bindinfo;
1634 DWORD cbindf = 0;
1635 HRESULT hres;
1637 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1638 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1639 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1640 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1641 ok(!pi, "pi = %x\n", pi);
1643 if(binding_test)
1644 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1646 memset(&bindinfo, 0, sizeof(bindinfo));
1647 bindinfo.cbSize = sizeof(bindinfo);
1648 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1649 SET_EXPECT(GetBindInfo);
1650 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1651 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1652 CHECK_CALLED(GetBindInfo);
1653 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1654 cbindf, (bindf|BINDF_FROMURLMON));
1655 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1656 pReleaseBindInfo(&bindinfo);
1658 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1659 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1660 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1661 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1663 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1664 IServiceProvider *service_provider;
1665 IHttpNegotiate *http_negotiate;
1666 IHttpNegotiate2 *http_negotiate2;
1667 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1668 LPWSTR additional_headers = NULL;
1669 BYTE sec_id[100];
1670 DWORD fetched = 0, size = 100;
1671 DWORD tid;
1673 SET_EXPECT(GetBindString_USER_AGENT);
1674 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1675 &ua, 1, &fetched);
1676 CHECK_CALLED(GetBindString_USER_AGENT);
1677 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1678 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1679 ok(ua != NULL, "ua = %p\n", ua);
1680 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1681 CoTaskMemFree(ua);
1683 fetched = 256;
1684 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1685 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1686 accept_mimes, 256, &fetched);
1687 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1689 ok(hres == S_OK,
1690 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1691 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1692 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1693 CoTaskMemFree(accept_mimes[0]);
1695 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1696 (void**)&service_provider);
1697 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1699 SET_EXPECT(QueryService_HttpNegotiate);
1700 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1701 &IID_IHttpNegotiate, (void**)&http_negotiate);
1702 CHECK_CALLED(QueryService_HttpNegotiate);
1703 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1705 SET_EXPECT(BeginningTransaction);
1706 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1707 NULL, 0, &additional_headers);
1708 CHECK_CALLED(BeginningTransaction);
1709 IHttpNegotiate_Release(http_negotiate);
1710 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1711 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1713 SET_EXPECT(QueryService_HttpNegotiate);
1714 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1715 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1716 CHECK_CALLED(QueryService_HttpNegotiate);
1717 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1719 size = 512;
1720 SET_EXPECT(GetRootSecurityId);
1721 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1722 CHECK_CALLED(GetRootSecurityId);
1723 IHttpNegotiate2_Release(http_negotiate2);
1724 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1725 ok(size == 13, "size=%d\n", size);
1727 IServiceProvider_Release(service_provider);
1729 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1730 return;
1733 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1734 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1735 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1736 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1737 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1739 if(mimefilter_test) {
1740 SET_EXPECT(MimeFilter_CreateInstance);
1741 SET_EXPECT(MimeFilter_Start);
1742 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1744 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1745 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1746 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1747 ok(hres == S_OK,
1748 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1749 if(mimefilter_test) {
1750 CHECK_CALLED(MimeFilter_CreateInstance);
1751 CHECK_CALLED(MimeFilter_Start);
1752 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1753 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1754 }else {
1755 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1758 if(mimefilter_test)
1759 SET_EXPECT(MimeFilter_ReportData);
1760 else
1761 SET_EXPECT(ReportData);
1762 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1763 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1764 13, 13);
1765 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1766 if(mimefilter_test)
1767 CHECK_CALLED(MimeFilter_ReportData);
1768 else
1769 CHECK_CALLED(ReportData);
1771 if(tested_protocol == ITS_TEST) {
1772 SET_EXPECT(ReportData);
1773 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1774 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1775 CHECK_CALLED(ReportData);
1778 if(tested_protocol == BIND_TEST) {
1779 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1780 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1783 if(mimefilter_test)
1784 SET_EXPECT(MimeFilter_ReportResult);
1785 else
1786 SET_EXPECT(ReportResult);
1787 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1788 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1789 if(mimefilter_test)
1790 CHECK_CALLED(MimeFilter_ReportResult);
1791 else
1792 CHECK_CALLED(ReportResult);
1795 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1796 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1797 DWORD grfPI, HANDLE_PTR dwReserved)
1799 CHECK_EXPECT(Start);
1801 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1802 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1803 return S_OK;
1806 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1807 PROTOCOLDATA *pProtocolData)
1809 DWORD bscf = 0, pr;
1810 HRESULT hres;
1812 CHECK_EXPECT(Continue);
1814 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1815 if(!pProtocolData || tested_protocol == BIND_TEST)
1816 return S_OK;
1817 if(binding_test) {
1818 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1819 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1820 pProtocolData->grfFlags, protocoldata.grfFlags );
1821 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1822 pProtocolData->dwState, protocoldata.dwState );
1823 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1824 pProtocolData->pData, protocoldata.pData );
1825 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1826 pProtocolData->cbData, protocoldata.cbData );
1829 switch(prot_state) {
1830 case 1: {
1831 IServiceProvider *service_provider;
1832 IHttpNegotiate *http_negotiate;
1833 static const WCHAR header[] = {'?',0};
1835 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1836 (void**)&service_provider);
1837 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1839 SET_EXPECT(QueryService_HttpNegotiate);
1840 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1841 &IID_IHttpNegotiate, (void**)&http_negotiate);
1842 IServiceProvider_Release(service_provider);
1843 CHECK_CALLED(QueryService_HttpNegotiate);
1844 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1846 SET_EXPECT(OnResponse);
1847 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1848 IHttpNegotiate_Release(http_negotiate);
1849 CHECK_CALLED(OnResponse);
1850 IHttpNegotiate_Release(http_negotiate);
1851 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1853 if(mimefilter_test) {
1854 SET_EXPECT(MimeFilter_CreateInstance);
1855 SET_EXPECT(MimeFilter_Start);
1856 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1857 }else if(!(pi & PI_MIMEVERIFICATION)) {
1858 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1860 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1861 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1862 if(mimefilter_test) {
1863 CHECK_CALLED(MimeFilter_CreateInstance);
1864 CHECK_CALLED(MimeFilter_Start);
1865 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1866 }else if(!(pi & PI_MIMEVERIFICATION)) {
1867 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1869 ok(hres == S_OK,
1870 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1872 bscf |= BSCF_FIRSTDATANOTIFICATION;
1873 break;
1875 case 2:
1876 case 3:
1877 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1878 break;
1881 pr = prot_read;
1882 if(mimefilter_test)
1883 SET_EXPECT(MimeFilter_ReportData);
1884 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1885 if(pr < 200)
1886 SET_EXPECT(Read); /* checked in ReportData for short_read */
1887 if(pr == 200) {
1888 if(!mimefilter_test)
1889 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1890 SET_EXPECT(GetBindInfo);
1891 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1893 if(pr >= 200)
1894 SET_EXPECT(ReportData);
1895 }else {
1896 SET_EXPECT(ReportData);
1899 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1900 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1902 if(mimefilter_test) {
1903 SET_EXPECT(MimeFilter_ReportData);
1904 }else if(pi & PI_MIMEVERIFICATION) {
1905 if(!short_read && pr < 200)
1906 CHECK_CALLED(Read);
1907 if(pr == 200) {
1908 CLEAR_CALLED(GetBindInfo); /* IE9 */
1909 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1911 }else {
1912 CHECK_CALLED(ReportData);
1915 if(prot_state == 3)
1916 prot_state = 4;
1918 return S_OK;
1921 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1923 CHECK_EXPECT(Terminate);
1924 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1925 return S_OK;
1928 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1929 ULONG cb, ULONG *pcbRead)
1931 if(read_report_data)
1932 CHECK_EXPECT2(Read2);
1934 if(mimefilter_test || short_read) {
1935 if(!read_report_data)
1936 CHECK_EXPECT2(Read);
1937 }else if((pi & PI_MIMEVERIFICATION)) {
1938 if(!read_report_data)
1939 CHECK_EXPECT2(Read);
1941 if(prot_read < 300) {
1942 ok(pv != expect_pv, "pv == expect_pv\n");
1943 if(prot_read < 300)
1944 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1945 else
1946 ok(cb == 700, "cb=%d\n", cb);
1947 }else {
1948 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1950 }else {
1951 if(!read_report_data)
1952 CHECK_EXPECT(Read);
1954 ok(pv == expect_pv, "pv != expect_pv\n");
1955 ok(cb == 1000, "cb=%d\n", cb);
1956 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1958 ok(pcbRead != NULL, "pcbRead == NULL\n");
1960 if(prot_state == 3 || (short_read && prot_state != 4)) {
1961 HRESULT hres;
1963 prot_state = 4;
1964 if(short_read) {
1965 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1966 SET_EXPECT(GetBindInfo);
1967 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1969 if(mimefilter_test)
1970 SET_EXPECT(MimeFilter_ReportData);
1971 else if(direct_read)
1972 SET_EXPECT(ReportData2);
1973 read_report_data++;
1974 hres = IInternetProtocolSink_ReportData(binding_sink,
1975 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1976 read_report_data--;
1977 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1978 if(short_read) {
1979 CLEAR_CALLED(GetBindInfo); /* IE9 */
1980 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1982 if(mimefilter_test)
1983 CHECK_CALLED(MimeFilter_ReportData);
1984 else if(direct_read)
1985 CHECK_CALLED(ReportData2);
1987 if(mimefilter_test)
1988 SET_EXPECT(MimeFilter_ReportResult);
1989 else
1990 SET_EXPECT(ReportResult);
1991 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1992 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1993 if(mimefilter_test)
1994 CHECK_CALLED(MimeFilter_ReportResult);
1995 else
1996 CHECK_CALLED(ReportResult);
1998 if(cb > 100)
1999 cb = 100;
2000 memset(pv, 'x', cb);
2001 if(cb>6)
2002 memcpy(pv, "gif87a", 6);
2003 prot_read += *pcbRead = cb;
2004 return S_OK;
2007 if(prot_state == 4) {
2008 *pcbRead = 0;
2009 return S_FALSE;
2012 if((async_read_pending = !async_read_pending)) {
2013 *pcbRead = 0;
2014 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
2017 if(cb > 100)
2018 cb = 100;
2019 memset(pv, 'x', cb);
2020 if(cb>6)
2021 memcpy(pv, "gif87a", 6);
2022 prot_read += *pcbRead = cb;
2023 return S_OK;
2026 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2028 CHECK_EXPECT(LockRequest);
2029 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2030 return S_OK;
2033 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2035 CHECK_EXPECT(UnlockRequest);
2036 return S_OK;
2039 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2040 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2041 DWORD grfPI, HANDLE *dwReserved)
2043 CHECK_EXPECT(StartEx);
2044 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2045 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2046 return S_OK;
2049 static const IInternetProtocolExVtbl ProtocolVtbl = {
2050 ProtocolEmul_QueryInterface,
2051 Protocol_AddRef,
2052 Protocol_Release,
2053 ProtocolEmul_Start,
2054 ProtocolEmul_Continue,
2055 Protocol_Abort,
2056 ProtocolEmul_Terminate,
2057 Protocol_Suspend,
2058 Protocol_Resume,
2059 ProtocolEmul_Read,
2060 Protocol_Seek,
2061 ProtocolEmul_LockRequest,
2062 ProtocolEmul_UnlockRequest,
2063 ProtocolEmul_StartEx
2066 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2068 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2070 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2071 *ppv = iface;
2072 return S_OK;
2075 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2076 *ppv = &mime_protocol_sink;
2077 return S_OK;
2080 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2081 *ppv = NULL;
2082 return E_NOINTERFACE;
2085 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2086 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2087 DWORD grfPI, HANDLE_PTR dwReserved)
2089 PROTOCOLFILTERDATA *data;
2090 LPOLESTR url_str = NULL;
2091 DWORD fetched = 0;
2092 BINDINFO bindinfo;
2093 DWORD cbindf = 0;
2094 HRESULT hres;
2096 CHECK_EXPECT(MimeFilter_Start);
2098 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2099 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2100 ok(dwReserved, "dwReserved == 0\n");
2101 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2102 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2104 if(binding_test) {
2105 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2106 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2107 }else {
2108 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2109 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2112 data = (void*)dwReserved;
2113 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2114 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2115 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2116 ok(!data->pUnk, "data->pUnk != NULL\n");
2117 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2118 if(binding_test) {
2119 IInternetProtocolSink *prot_sink;
2121 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2122 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2123 IInternetProtocolSink_Release(prot_sink);
2125 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2127 filtered_protocol = data->pProtocol;
2128 IInternetProtocol_AddRef(filtered_protocol);
2129 }else {
2130 IInternetProtocol *prot;
2132 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2133 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2134 IInternetProtocol_Release(prot);
2136 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2139 filtered_sink = pOIProtSink;
2141 SET_EXPECT(ReportProgress_DECODING);
2142 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2143 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2144 CHECK_CALLED(ReportProgress_DECODING);
2146 SET_EXPECT(GetBindInfo);
2147 memset(&bindinfo, 0, sizeof(bindinfo));
2148 bindinfo.cbSize = sizeof(bindinfo);
2149 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2150 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2151 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2152 CHECK_CALLED(GetBindInfo);
2154 SET_EXPECT(GetBindString_URL);
2155 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2156 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2157 ok(fetched == 1, "fetched = %d\n", fetched);
2158 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2159 CoTaskMemFree(url_str);
2160 CHECK_CALLED(GetBindString_URL);
2162 return S_OK;
2165 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2166 PROTOCOLDATA *pProtocolData)
2168 CHECK_EXPECT(MimeFilter_Continue);
2169 return E_NOTIMPL;
2172 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2174 HRESULT hres;
2176 CHECK_EXPECT(MimeFilter_Terminate);
2178 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2180 SET_EXPECT(Terminate);
2181 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2182 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2183 CHECK_CALLED(Terminate);
2185 return S_OK;
2188 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2189 ULONG cb, ULONG *pcbRead)
2191 BYTE buf[2096];
2192 DWORD read = 0;
2193 HRESULT hres;
2195 CHECK_EXPECT(MimeFilter_Read);
2197 ok(pv != NULL, "pv == NULL\n");
2198 ok(cb != 0, "cb == 0\n");
2199 ok(pcbRead != NULL, "pcbRead == NULL\n");
2201 if(read_report_data)
2202 SET_EXPECT(Read2);
2203 else
2204 SET_EXPECT(Read);
2205 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2206 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2207 if(read_report_data)
2208 CHECK_CALLED(Read2);
2209 else
2210 CHECK_CALLED(Read);
2212 if(pcbRead) {
2213 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2214 *pcbRead = read;
2217 memset(pv, 'x', read);
2218 return hres;
2221 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2223 HRESULT hres;
2225 CHECK_EXPECT(MimeFilter_LockRequest);
2227 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2229 SET_EXPECT(LockRequest);
2230 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2231 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2232 CHECK_CALLED(LockRequest);
2234 return S_OK;
2237 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2239 HRESULT hres;
2241 CHECK_EXPECT(MimeFilter_UnlockRequest);
2243 SET_EXPECT(UnlockRequest);
2244 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2245 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2246 CHECK_CALLED(UnlockRequest);
2248 return S_OK;
2251 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2252 MimeProtocol_QueryInterface,
2253 Protocol_AddRef,
2254 Protocol_Release,
2255 MimeProtocol_Start,
2256 Protocol_Continue,
2257 Protocol_Abort,
2258 MimeProtocol_Terminate,
2259 Protocol_Suspend,
2260 Protocol_Resume,
2261 MimeProtocol_Read,
2262 Protocol_Seek,
2263 MimeProtocol_LockRequest,
2264 MimeProtocol_UnlockRequest
2267 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2269 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2271 ok(0, "unexpected call\n");
2272 return E_NOINTERFACE;
2275 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2277 return 2;
2280 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2282 return 1;
2285 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2286 REFIID riid, void **ppv)
2288 CHECK_EXPECT(CreateInstance);
2290 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2291 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2292 ok(ppv != NULL, "ppv == NULL\n");
2294 *ppv = &Protocol;
2295 return S_OK;
2298 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2300 ok(0, "unexpected call\n");
2301 return S_OK;
2304 static const IClassFactoryVtbl ClassFactoryVtbl = {
2305 ClassFactory_QueryInterface,
2306 ClassFactory_AddRef,
2307 ClassFactory_Release,
2308 ClassFactory_CreateInstance,
2309 ClassFactory_LockServer
2312 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2314 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2316 CHECK_EXPECT(MimeFilter_CreateInstance);
2318 ok(!outer, "outer = %p\n", outer);
2319 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2321 *ppv = &MimeProtocol;
2322 return S_OK;
2325 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2326 ClassFactory_QueryInterface,
2327 ClassFactory_AddRef,
2328 ClassFactory_Release,
2329 MimeFilter_CreateInstance,
2330 ClassFactory_LockServer
2333 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2335 #define TEST_BINDING 0x0001
2336 #define TEST_FILTER 0x0002
2337 #define TEST_FIRST_HTTP 0x0004
2338 #define TEST_DIRECT_READ 0x0008
2339 #define TEST_POST 0x0010
2340 #define TEST_EMULATEPROT 0x0020
2341 #define TEST_SHORT_READ 0x0040
2342 #define TEST_REDIRECT 0x0080
2343 #define TEST_ABORT 0x0100
2344 #define TEST_ASYNCREQ 0x0200
2345 #define TEST_USEIURI 0x0400
2346 #define TEST_IMPLPROTEX 0x0800
2347 #define TEST_EMPTY 0x1000
2348 #define TEST_NOMIME 0x2000
2349 #define TEST_FROMCACHE 0x4000
2351 static void register_filter(BOOL do_register)
2353 IInternetSession *session;
2354 HRESULT hres;
2356 hres = pCoInternetGetSession(0, &session, 0);
2357 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2359 if(do_register) {
2360 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2361 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2362 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2363 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2364 }else {
2365 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2366 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2367 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2368 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2371 IInternetSession_Release(session);
2374 static void init_test(int prot, DWORD flags)
2376 tested_protocol = prot;
2377 binding_test = (flags & TEST_BINDING) != 0;
2378 first_data_notif = TRUE;
2379 prot_read = 0;
2380 prot_state = 0;
2381 async_read_pending = TRUE;
2382 mimefilter_test = (flags & TEST_FILTER) != 0;
2383 no_mime = (flags & TEST_NOMIME) != 0;
2384 filter_state = 0;
2385 post_stream_read = 0;
2386 ResetEvent(event_complete);
2387 ResetEvent(event_complete2);
2388 ResetEvent(event_continue);
2389 ResetEvent(event_continue_done);
2390 async_protocol = binding_protocol = filtered_protocol = NULL;
2391 filtered_sink = NULL;
2392 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2393 first_data_notif = TRUE;
2394 state = STATE_CONNECTING;
2395 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2396 direct_read = (flags & TEST_DIRECT_READ) != 0;
2397 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2398 wait_for_switch = TRUE;
2399 short_read = (flags & TEST_SHORT_READ) != 0;
2400 http_post_test = TYMED_NULL;
2401 test_redirect = (flags & TEST_REDIRECT) != 0;
2402 test_abort = (flags & TEST_ABORT) != 0;
2403 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2404 empty_file = (flags & TEST_EMPTY) != 0;
2405 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2406 file_with_hash = FALSE;
2408 register_filter(mimefilter_test);
2411 static void test_priority(IInternetProtocol *protocol)
2413 IInternetPriority *priority;
2414 LONG pr;
2415 HRESULT hres;
2417 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2418 (void**)&priority);
2419 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2420 if(FAILED(hres))
2421 return;
2423 hres = IInternetPriority_GetPriority(priority, &pr);
2424 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2425 ok(pr == 0, "pr=%d, expected 0\n", pr);
2427 hres = IInternetPriority_SetPriority(priority, 1);
2428 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2430 hres = IInternetPriority_GetPriority(priority, &pr);
2431 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2432 ok(pr == 1, "pr=%d, expected 1\n", pr);
2434 IInternetPriority_Release(priority);
2437 static void test_early_abort(const CLSID *clsid)
2439 IInternetProtocol *protocol;
2440 HRESULT hres;
2442 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2443 &IID_IInternetProtocol, (void**)&protocol);
2444 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2446 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2447 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2449 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2450 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2452 IInternetProtocol_Release(protocol);
2455 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2456 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2458 HRESULT hres;
2460 SET_EXPECT(GetBindInfo);
2461 if(!(bindf & BINDF_FROMURLMON))
2462 SET_EXPECT(ReportProgress_DIRECTBIND);
2463 if(is_first) {
2464 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2465 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2466 if(bindf & BINDF_FROMURLMON)
2467 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2468 else
2469 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2471 SET_EXPECT(ReportData);
2472 if(is_first)
2473 SET_EXPECT(ReportResult);
2475 expect_hrResult = S_OK;
2477 if(protocolex) {
2478 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2479 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2480 }else {
2481 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2482 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2483 win_skip("Start failed\n");
2484 return FALSE;
2486 ok(hres == S_OK, "Start failed: %08x\n", hres);
2489 CHECK_CALLED(GetBindInfo);
2490 if(!(bindf & BINDF_FROMURLMON))
2491 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2492 if(is_first) {
2493 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2494 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2495 if(bindf & BINDF_FROMURLMON)
2496 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2497 else
2498 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2500 CHECK_CALLED(ReportData);
2501 if(is_first)
2502 CHECK_CALLED(ReportResult);
2504 return TRUE;
2507 static void test_file_protocol_url(LPCWSTR url)
2509 IInternetProtocolInfo *protocol_info;
2510 IUnknown *unk;
2511 IClassFactory *factory;
2512 IInternetProtocol *protocol;
2513 BYTE buf[512];
2514 ULONG cb;
2515 HRESULT hres;
2517 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2518 &IID_IUnknown, (void**)&unk);
2519 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2520 if(FAILED(hres))
2521 return;
2523 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2524 ok(hres == E_NOINTERFACE,
2525 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2527 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2528 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2529 IUnknown_Release(unk);
2530 if(FAILED(hres))
2531 return;
2533 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2534 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2536 if(SUCCEEDED(hres)) {
2537 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2538 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2539 ok(hres == S_OK, "Read failed: %08x\n", hres);
2540 ok(cb == 2, "cb=%u expected 2\n", cb);
2541 buf[2] = 0;
2542 ok(!memcmp(buf, file_with_hash ? "XX" : "<H", 2), "Unexpected data %s\n", buf);
2543 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2544 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2545 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2546 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2547 ok(cb == 0, "cb=%u expected 0\n", cb);
2548 hres = IInternetProtocol_UnlockRequest(protocol);
2549 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2552 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2553 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2554 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2555 hres = IInternetProtocol_LockRequest(protocol, 0);
2556 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2557 hres = IInternetProtocol_UnlockRequest(protocol);
2558 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2561 IInternetProtocol_Release(protocol);
2564 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2565 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2566 if(SUCCEEDED(hres)) {
2567 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2568 hres = IInternetProtocol_LockRequest(protocol, 0);
2569 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2570 hres = IInternetProtocol_Terminate(protocol, 0);
2571 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2572 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2573 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2574 hres = IInternetProtocol_UnlockRequest(protocol);
2575 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2576 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2577 if(file_with_hash) /* FIXME: An effect of UnlockRequest call? */
2578 todo_wine ok(hres == S_OK, "Read failed: %08x\n", hres);
2579 else
2580 ok(hres == S_OK, "Read failed: %08x\n", hres);
2581 hres = IInternetProtocol_Terminate(protocol, 0);
2582 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2585 IInternetProtocol_Release(protocol);
2588 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2589 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2590 if(SUCCEEDED(hres)) {
2591 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2592 hres = IInternetProtocol_Terminate(protocol, 0);
2593 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2594 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2595 ok(hres == S_OK, "Read failed: %08x\n", hres);
2596 ok(cb == 2, "cb=%u expected 2\n", cb);
2599 IInternetProtocol_Release(protocol);
2602 if(pCreateUri) {
2603 IInternetProtocolEx *protocolex;
2604 IUri *uri;
2606 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2607 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2609 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2610 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2612 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2613 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2614 ok(hres == S_OK, "Read failed: %08x\n", hres);
2615 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2616 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2617 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2618 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2621 IUri_Release(uri);
2622 IInternetProtocolEx_Release(protocolex);
2624 hres = pCreateUri(url, 0, 0, &uri);
2625 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2627 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2628 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2630 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2631 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2632 ok(hres == S_OK, "Read failed: %08x\n", hres);
2633 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2634 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2635 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2636 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2639 IUri_Release(uri);
2640 IInternetProtocolEx_Release(protocolex);
2641 }else {
2642 win_skip("Skipping file protocol StartEx tests\n");
2645 IClassFactory_Release(factory);
2648 static void test_file_protocol_fail(void)
2650 IInternetProtocol *protocol;
2651 HRESULT hres;
2653 static const WCHAR index_url2[] =
2654 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2656 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2657 &IID_IInternetProtocol, (void**)&protocol);
2658 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2659 if(FAILED(hres))
2660 return;
2662 SET_EXPECT(GetBindInfo);
2663 expect_hrResult = MK_E_SYNTAX;
2664 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2665 ok(hres == MK_E_SYNTAX ||
2666 hres == E_INVALIDARG,
2667 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2668 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2670 SET_EXPECT(GetBindInfo);
2671 if(!(bindf & BINDF_FROMURLMON))
2672 SET_EXPECT(ReportProgress_DIRECTBIND);
2673 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2674 SET_EXPECT(ReportResult);
2675 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2676 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2677 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2678 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2679 CHECK_CALLED(GetBindInfo);
2680 if(!(bindf & BINDF_FROMURLMON))
2681 CHECK_CALLED(ReportProgress_DIRECTBIND);
2682 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2683 CHECK_CALLED(ReportResult);
2685 IInternetProtocol_Release(protocol);
2687 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2688 &IID_IInternetProtocol, (void**)&protocol);
2689 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2690 if(FAILED(hres))
2691 return;
2693 SET_EXPECT(GetBindInfo);
2694 if(!(bindf & BINDF_FROMURLMON))
2695 SET_EXPECT(ReportProgress_DIRECTBIND);
2696 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2697 SET_EXPECT(ReportResult);
2698 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2700 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2701 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2702 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2703 CHECK_CALLED(GetBindInfo);
2704 if(!(bindf & BINDF_FROMURLMON))
2705 CHECK_CALLED(ReportProgress_DIRECTBIND);
2706 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2707 CHECK_CALLED(ReportResult);
2709 SET_EXPECT(GetBindInfo);
2710 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2711 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2712 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2714 SET_EXPECT(GetBindInfo);
2715 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2716 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2717 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2719 IInternetProtocol_Release(protocol);
2722 static void test_file_protocol(void) {
2723 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2724 DWORD size;
2725 ULONG len;
2726 HANDLE file;
2728 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2729 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2730 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2731 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2732 static const char html_doc[] = "<HTML></HTML>";
2733 static const WCHAR fragmentW[] = {'#','f','r','a','g',0};
2735 trace("Testing file protocol...\n");
2736 init_test(FILE_TEST, 0);
2738 SetLastError(0xdeadbeef);
2739 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2740 FILE_ATTRIBUTE_NORMAL, NULL);
2741 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2742 if(file == INVALID_HANDLE_VALUE)
2743 return;
2744 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2745 CloseHandle(file);
2747 file_name = wszIndexHtml;
2748 bindf = 0;
2749 test_file_protocol_url(index_url);
2750 bindf = BINDF_FROMURLMON;
2751 test_file_protocol_url(index_url);
2752 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2753 test_file_protocol_url(index_url);
2755 memcpy(buf, wszFile, sizeof(wszFile));
2756 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2757 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2758 buf[len++] = '\\';
2759 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2761 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2762 bindf = 0;
2763 test_file_protocol_url(buf);
2764 bindf = BINDF_FROMURLMON;
2765 test_file_protocol_url(buf);
2767 memcpy(buf, wszFile2, sizeof(wszFile2));
2768 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2769 file_name_buf[len++] = '\\';
2770 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2771 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2772 file_name = file_name_buf;
2773 bindf = 0;
2774 test_file_protocol_url(buf);
2775 bindf = BINDF_FROMURLMON;
2776 test_file_protocol_url(buf);
2778 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2779 test_file_protocol_url(buf);
2781 memcpy(buf, wszFile3, sizeof(wszFile3));
2782 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2783 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2784 buf[len++] = '\\';
2785 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2787 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2788 bindf = 0;
2789 test_file_protocol_url(buf);
2790 bindf = BINDF_FROMURLMON;
2791 test_file_protocol_url(buf);
2793 memcpy(buf, wszFile4, sizeof(wszFile4));
2794 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2795 file_name_buf[len++] = '\\';
2796 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2797 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2798 file_name = file_name_buf;
2799 bindf = 0;
2800 test_file_protocol_url(buf);
2801 bindf = BINDF_FROMURLMON;
2802 test_file_protocol_url(buf);
2804 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2805 test_file_protocol_url(buf);
2807 /* Fragment part of URL is skipped if the file doesn't exist. */
2808 lstrcatW(buf, fragmentW);
2809 test_file_protocol_url(buf);
2811 /* Fragment part is considered a part of the file name, if the file exsists. */
2812 len = lstrlenW(file_name_buf);
2813 lstrcpyW(file_name_buf+len, fragmentW);
2814 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2815 FILE_ATTRIBUTE_NORMAL, NULL);
2816 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2817 WriteFile(file, "XXX", 3, &size, NULL);
2818 CloseHandle(file);
2819 file_name_buf[len] = 0;
2821 file_with_hash = TRUE;
2822 test_file_protocol_url(buf);
2824 DeleteFileW(wszIndexHtml);
2825 DeleteFileW(file_name_buf);
2827 bindf = 0;
2828 test_file_protocol_fail();
2829 bindf = BINDF_FROMURLMON;
2830 test_file_protocol_fail();
2833 static void create_cache_entry(const WCHAR *urlw)
2835 FILETIME now, tomorrow, yesterday;
2836 char file_path[MAX_PATH];
2837 BYTE content[1000];
2838 ULARGE_INTEGER li;
2839 const char *url;
2840 HANDLE file;
2841 DWORD size;
2842 unsigned i;
2843 BOOL res;
2845 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2847 trace("Testing cache read...\n");
2849 url = w2a(urlw);
2851 for(i = 0; i < sizeof(content); i++)
2852 content[i] = '0' + (i%10);
2854 GetSystemTimeAsFileTime(&now);
2855 li.u.HighPart = now.dwHighDateTime;
2856 li.u.LowPart = now.dwLowDateTime;
2857 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2858 tomorrow.dwHighDateTime = li.u.HighPart;
2859 tomorrow.dwLowDateTime = li.u.LowPart;
2860 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2861 yesterday.dwHighDateTime = li.u.HighPart;
2862 yesterday.dwLowDateTime = li.u.LowPart;
2864 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2865 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2867 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2868 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2870 WriteFile(file, content, sizeof(content), &size, NULL);
2871 CloseHandle(file);
2873 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2874 cache_headers, sizeof(cache_headers)-1, "", 0);
2875 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2878 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2880 static BOOL got_user_agent = FALSE;
2881 IUri *uri = NULL;
2882 HRESULT hres;
2884 if(use_iuri && pCreateUri) {
2885 hres = pCreateUri(url, 0, 0, &uri);
2886 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2889 SET_EXPECT(GetBindInfo);
2890 if (!(bindf & BINDF_FROMURLMON))
2891 SET_EXPECT(ReportProgress_DIRECTBIND);
2892 if(!got_user_agent)
2893 SET_EXPECT(GetBindString_USER_AGENT);
2894 SET_EXPECT(GetBindString_ROOTDOC_URL);
2895 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2896 SET_EXPECT(QueryService_HttpNegotiate);
2897 SET_EXPECT(BeginningTransaction);
2898 SET_EXPECT(GetRootSecurityId);
2899 if(http_post_test) {
2900 SET_EXPECT(GetBindString_POST_COOKIE);
2901 if(http_post_test == TYMED_ISTREAM)
2902 SET_EXPECT(Stream_Seek);
2904 if(bind_from_cache) {
2905 SET_EXPECT(OnResponse);
2906 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2907 SET_EXPECT(ReportData);
2910 if(uri) {
2911 IInternetProtocolEx *protocolex;
2913 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2914 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2916 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2917 ok(hres == S_OK, "Start failed: %08x\n", hres);
2919 IInternetProtocolEx_Release(protocolex);
2920 IUri_Release(uri);
2921 }else {
2922 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2923 ok(hres == S_OK, "Start failed: %08x\n", hres);
2925 if(FAILED(hres))
2926 return FALSE;
2928 CHECK_CALLED(GetBindInfo);
2929 if (!(bindf & BINDF_FROMURLMON))
2930 CHECK_CALLED(ReportProgress_DIRECTBIND);
2931 if (!got_user_agent)
2933 CHECK_CALLED(GetBindString_USER_AGENT);
2934 got_user_agent = TRUE;
2936 CLEAR_CALLED(GetBindString_ROOTDOC_URL); /* New in IE11 */
2937 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2938 CHECK_CALLED(QueryService_HttpNegotiate);
2939 CHECK_CALLED(BeginningTransaction);
2940 /* GetRootSecurityId called on WinXP but not on Win98 */
2941 CLEAR_CALLED(GetRootSecurityId);
2942 if(http_post_test) {
2943 CHECK_CALLED(GetBindString_POST_COOKIE);
2944 if(http_post_test == TYMED_ISTREAM)
2945 CHECK_CALLED(Stream_Seek);
2947 if(bind_from_cache) {
2948 CHECK_CALLED(OnResponse);
2949 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2950 CHECK_CALLED(ReportData);
2953 return TRUE;
2956 static void test_protocol_terminate(IInternetProtocol *protocol)
2958 BYTE buf[3600];
2959 DWORD cb;
2960 HRESULT hres;
2962 hres = IInternetProtocol_LockRequest(protocol, 0);
2963 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2965 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2966 ok(hres == (test_abort ? S_OK : S_FALSE), "Read failed: %08x\n", hres);
2968 hres = IInternetProtocol_Terminate(protocol, 0);
2969 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2971 /* This wait is to give the internet handles being freed in Terminate
2972 * enough time to actually terminate in all cases. Internet handles
2973 * terminate asynchronously and native reuses the main InternetOpen
2974 * handle. The only case in which this seems to be necessary is on
2975 * wine with native wininet and urlmon, resulting in the next time
2976 * test_http_protocol_url being called the first data notification actually
2977 * being an extra last data notification from the previous connection
2978 * about once out of every ten times. */
2979 Sleep(100);
2981 hres = IInternetProtocol_UnlockRequest(protocol);
2982 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2985 static void test_http_info(IInternetProtocol *protocol)
2987 IWinInetHttpInfo *info;
2988 HRESULT hres;
2990 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2991 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2993 /* TODO */
2995 IWinInetHttpInfo_Release(info);
2998 /* is_first refers to whether this is the first call to this function
2999 * _for this url_ */
3000 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
3002 IInternetProtocolInfo *protocol_info;
3003 IClassFactory *factory;
3004 IUnknown *unk;
3005 HRESULT hres;
3007 init_test(prot, flags);
3008 http_url = url;
3009 http_post_test = tymed;
3011 if(flags & TEST_FROMCACHE)
3012 create_cache_entry(url);
3014 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
3015 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3016 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3017 if(FAILED(hres))
3018 return;
3020 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3021 ok(hres == E_NOINTERFACE,
3022 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3023 hres);
3025 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3026 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3027 IUnknown_Release(unk);
3028 if(FAILED(hres))
3029 return;
3031 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3032 (void**)&async_protocol);
3033 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3034 if(SUCCEEDED(hres)) {
3035 BYTE buf[3600];
3036 DWORD cb;
3037 ULONG ref;
3039 test_priority(async_protocol);
3040 test_http_info(async_protocol);
3042 SET_EXPECT(ReportProgress_COOKIE_SENT);
3043 if(http_is_first) {
3044 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3045 SET_EXPECT(ReportProgress_CONNECTING);
3047 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3048 if(test_redirect)
3049 SET_EXPECT(ReportProgress_REDIRECTING);
3050 SET_EXPECT(ReportProgress_PROXYDETECTING);
3051 if(prot == HTTP_TEST)
3052 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3053 else
3054 SET_EXPECT(QueryService_HttpSecurity);
3055 if(!(bindf & BINDF_FROMURLMON)) {
3056 SET_EXPECT(OnResponse);
3057 SET_EXPECT(ReportProgress_RAWMIMETYPE);
3058 SET_EXPECT(ReportData);
3059 } else {
3060 SET_EXPECT(Switch);
3063 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3064 IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3065 IInternetProtocol_Release(async_protocol);
3066 return;
3069 if(!direct_read && !test_abort && !bind_from_cache)
3070 SET_EXPECT(ReportResult);
3071 expect_hrResult = test_abort ? E_ABORT : S_OK;
3073 if(direct_read) {
3074 SET_EXPECT(Switch);
3075 while(wait_for_switch) {
3076 ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3077 CHECK_CALLED(Switch); /* Set in ReportData */
3078 call_continue(&continue_protdata);
3079 SetEvent(event_continue_done);
3081 }else if(bind_from_cache) {
3082 BYTE buf[1500];
3084 hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3085 ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3087 SET_EXPECT(ReportResult);
3088 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3089 ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3090 CHECK_CALLED(ReportResult);
3092 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3093 ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3094 }else {
3095 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3096 ok((hres == E_PENDING && cb==0) ||
3097 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3099 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3100 if(bindf & BINDF_FROMURLMON)
3101 CHECK_CALLED(Switch);
3102 else
3103 CHECK_CALLED(ReportData);
3104 if(prot == HTTPS_TEST)
3105 CLEAR_CALLED(QueryService_HttpSecurity);
3107 while(1) {
3108 if(bindf & BINDF_FROMURLMON)
3109 SET_EXPECT(Switch);
3110 else
3111 SET_EXPECT(ReportData);
3112 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3113 if(hres == E_PENDING) {
3114 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3115 ok((hres == E_PENDING && cb==0) ||
3116 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3117 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3118 if(bindf & BINDF_FROMURLMON)
3119 CHECK_CALLED(Switch);
3120 else
3121 CHECK_CALLED(ReportData);
3123 if(test_abort) {
3124 HRESULT hres;
3126 SET_EXPECT(ReportResult);
3127 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3128 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3129 CHECK_CALLED(ReportResult);
3131 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3132 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3133 break;
3135 }else {
3136 if(bindf & BINDF_FROMURLMON)
3137 CHECK_NOT_CALLED(Switch);
3138 else
3139 CHECK_NOT_CALLED(ReportData);
3140 if(cb == 0) break;
3143 if(!test_abort) {
3144 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3145 CHECK_CALLED(ReportResult);
3148 if(prot == HTTPS_TEST)
3149 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3151 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3152 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3154 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3155 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3157 test_protocol_terminate(async_protocol);
3159 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3160 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3162 ref = IInternetProtocol_Release(async_protocol);
3163 ok(!ref, "ref=%x\n", ref);
3166 IClassFactory_Release(factory);
3168 if(flags & TEST_FROMCACHE) {
3169 BOOL res;
3171 res = DeleteUrlCacheEntryW(url);
3172 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3176 static void test_http_protocol(void)
3178 static const WCHAR posttest_url[] =
3179 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3180 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3181 static const WCHAR redirect_url[] =
3182 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3183 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3184 static const WCHAR winetest_url[] =
3185 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3186 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3187 static const WCHAR empty_url[] =
3188 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3189 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3190 static const WCHAR cache_only_url[] =
3191 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3192 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3195 trace("Testing http protocol (not from urlmon)...\n");
3196 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3197 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3199 trace("Testing http protocol (from urlmon)...\n");
3200 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3201 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3203 trace("Testing http protocol (to file)...\n");
3204 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3205 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3207 trace("Testing http protocol (post data)...\n");
3208 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3209 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3211 trace("Testing http protocol (post data stream)...\n");
3212 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3214 trace("Testing http protocol (direct read)...\n");
3215 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3216 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3218 trace("Testing http protocol (redirected)...\n");
3219 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3220 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3222 trace("Testing http protocol empty file...\n");
3223 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3224 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3226 /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3227 * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3228 * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3229 * tests work on Windows and have them around for the future.
3231 if(broken(1)) {
3232 trace("Testing http protocol (from cache)...\n");
3233 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3234 test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3237 trace("Testing http protocol abort...\n");
3238 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3239 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3241 test_early_abort(&CLSID_HttpProtocol);
3242 test_early_abort(&CLSID_HttpSProtocol);
3245 static void test_https_protocol(void)
3247 static const WCHAR https_winehq_url[] =
3248 {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3249 't','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
3251 trace("Testing https protocol (from urlmon)...\n");
3252 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3253 test_http_protocol_url(https_winehq_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3257 static void test_ftp_protocol(void)
3259 IInternetProtocolInfo *protocol_info;
3260 IClassFactory *factory;
3261 IUnknown *unk;
3262 BYTE buf[4096];
3263 ULONG ref;
3264 DWORD cb;
3265 HRESULT hres;
3267 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3268 '/','p','u','b','/','o','t','h','e','r','/',
3269 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3271 trace("Testing ftp protocol...\n");
3273 init_test(FTP_TEST, 0);
3275 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3276 state = STATE_STARTDOWNLOADING;
3277 expect_hrResult = E_PENDING;
3279 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3280 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3281 if(FAILED(hres))
3282 return;
3284 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3285 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3287 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3288 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3289 IUnknown_Release(unk);
3290 if(FAILED(hres))
3291 return;
3293 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3294 (void**)&async_protocol);
3295 IClassFactory_Release(factory);
3296 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3298 test_priority(async_protocol);
3299 test_http_info(async_protocol);
3301 SET_EXPECT(GetBindInfo);
3302 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3303 SET_EXPECT(ReportProgress_CONNECTING);
3304 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3305 SET_EXPECT(Switch);
3307 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
3308 ok(hres == S_OK, "Start failed: %08x\n", hres);
3309 CHECK_CALLED(GetBindInfo);
3311 SET_EXPECT(ReportResult);
3313 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3314 ok((hres == E_PENDING && cb==0) ||
3315 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3317 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3319 while(1) {
3320 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3321 if(hres == E_PENDING)
3323 DWORD ret = WaitForSingleObject(event_complete, 90000);
3324 ok( ret == WAIT_OBJECT_0, "wait timed out\n" );
3325 if (ret != WAIT_OBJECT_0) break;
3327 else
3328 if(cb == 0) break;
3331 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3332 CHECK_CALLED(ReportResult);
3333 CHECK_CALLED(Switch);
3335 test_protocol_terminate(async_protocol);
3337 if(pCreateUri) {
3338 IInternetProtocolEx *protocolex;
3340 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3341 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3342 IInternetProtocolEx_Release(protocolex);
3345 ref = IInternetProtocol_Release(async_protocol);
3346 ok(!ref, "ref=%d\n", ref);
3348 test_early_abort(&CLSID_FtpProtocol);
3351 static void test_gopher_protocol(void)
3353 IInternetProtocolInfo *protocol_info;
3354 IClassFactory *factory;
3355 IUnknown *unk;
3356 HRESULT hres;
3358 trace("Testing gopher protocol...\n");
3360 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3361 ok(hres == S_OK ||
3362 broken(hres == REGDB_E_CLASSNOTREG || hres == CLASS_E_CLASSNOTAVAILABLE), /* Gopher protocol has been removed as of Vista */
3363 "CoGetClassObject failed: %08x\n", hres);
3364 if(FAILED(hres))
3365 return;
3367 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3368 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3370 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3371 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3372 IUnknown_Release(unk);
3373 if(FAILED(hres))
3374 return;
3376 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3377 (void**)&async_protocol);
3378 IClassFactory_Release(factory);
3379 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3381 test_priority(async_protocol);
3383 IInternetProtocol_Release(async_protocol);
3385 test_early_abort(&CLSID_GopherProtocol);
3388 static void test_mk_protocol(void)
3390 IInternetProtocolInfo *protocol_info;
3391 IInternetProtocol *protocol;
3392 IClassFactory *factory;
3393 IUnknown *unk;
3394 HRESULT hres;
3396 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
3397 ':',':','/','t','e','s','t','.','h','t','m','l',0};
3398 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
3400 trace("Testing mk protocol...\n");
3401 init_test(MK_TEST, 0);
3403 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
3404 &IID_IUnknown, (void**)&unk);
3405 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3407 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3408 ok(hres == E_NOINTERFACE,
3409 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3410 hres);
3412 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3413 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3414 IUnknown_Release(unk);
3415 if(FAILED(hres))
3416 return;
3418 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3419 (void**)&protocol);
3420 IClassFactory_Release(factory);
3421 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3423 SET_EXPECT(GetBindInfo);
3424 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
3425 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
3426 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
3427 CLEAR_CALLED(GetBindInfo);
3429 SET_EXPECT(GetBindInfo);
3430 SET_EXPECT(ReportProgress_DIRECTBIND);
3431 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3432 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3433 SET_EXPECT(ReportResult);
3434 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3436 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
3437 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
3438 hres == INET_E_INVALID_URL, /* win2k3 */
3439 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
3441 if (hres == INET_E_RESOURCE_NOT_FOUND) {
3442 CHECK_CALLED(GetBindInfo);
3443 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3444 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3445 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3446 CHECK_CALLED(ReportResult);
3447 }else {
3448 CLEAR_CALLED(GetBindInfo);
3449 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3450 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3451 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3452 CLEAR_CALLED(ReportResult);
3455 IInternetProtocol_Release(protocol);
3458 static void test_CreateBinding(void)
3460 IInternetProtocol *protocol;
3461 IInternetPriority *priority;
3462 IInternetSession *session;
3463 IWinInetHttpInfo *http_info;
3464 IWinInetInfo *inet_info;
3465 LONG p;
3466 BYTE buf[1000];
3467 DWORD read;
3468 HRESULT hres;
3470 static const WCHAR test_url[] =
3471 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
3472 static const WCHAR wsz_test[] = {'t','e','s','t',0};
3474 trace("Testing CreateBinding...\n");
3475 init_test(BIND_TEST, TEST_BINDING);
3477 hres = pCoInternetGetSession(0, &session, 0);
3478 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3480 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
3481 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3483 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3484 binding_protocol = protocol;
3485 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3486 ok(protocol != NULL, "protocol == NULL\n");
3488 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3489 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3491 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3492 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
3494 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
3495 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3496 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
3497 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3498 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3499 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3501 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
3502 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
3504 p = 0xdeadbeef;
3505 hres = IInternetPriority_GetPriority(priority, &p);
3506 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3507 ok(!p, "p=%d\n", p);
3509 ex_priority = 100;
3510 hres = IInternetPriority_SetPriority(priority, 100);
3511 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3513 p = 0xdeadbeef;
3514 hres = IInternetPriority_GetPriority(priority, &p);
3515 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3516 ok(p == 100, "p=%d\n", p);
3518 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3519 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3521 SET_EXPECT(QueryService_InternetProtocol);
3522 SET_EXPECT(CreateInstance);
3523 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3524 SET_EXPECT(SetPriority);
3525 SET_EXPECT(Start);
3527 expect_hrResult = S_OK;
3528 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3529 ok(hres == S_OK, "Start failed: %08x\n", hres);
3531 CHECK_CALLED(QueryService_InternetProtocol);
3532 CHECK_CALLED(CreateInstance);
3533 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3534 CHECK_CALLED(SetPriority);
3535 CHECK_CALLED(Start);
3537 SET_EXPECT(QueryInterface_IWinInetInfo);
3538 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3539 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3540 CHECK_CALLED(QueryInterface_IWinInetInfo);
3542 SET_EXPECT(QueryInterface_IWinInetInfo);
3543 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3544 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3545 CHECK_CALLED(QueryInterface_IWinInetInfo);
3547 SET_EXPECT(QueryInterface_IWinInetHttpInfo);
3548 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
3549 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3550 CHECK_CALLED(QueryInterface_IWinInetHttpInfo);
3552 SET_EXPECT(Read);
3553 read = 0xdeadbeef;
3554 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3555 ok(hres == S_OK, "Read failed: %08x\n", hres);
3556 ok(read == 100, "read = %d\n", read);
3557 CHECK_CALLED(Read);
3559 SET_EXPECT(Read);
3560 read = 0xdeadbeef;
3561 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3562 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3563 ok(!read, "read = %d\n", read);
3564 CHECK_CALLED(Read);
3566 p = 0xdeadbeef;
3567 hres = IInternetPriority_GetPriority(priority, &p);
3568 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3569 ok(p == 100, "p=%d\n", p);
3571 hres = IInternetPriority_SetPriority(priority, 101);
3572 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3574 SET_EXPECT(Terminate);
3575 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
3576 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3577 CHECK_CALLED(Terminate);
3579 SET_EXPECT(Continue);
3580 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
3581 ok(hres == S_OK, "Switch failed: %08x\n", hres);
3582 CHECK_CALLED(Continue);
3584 hres = IInternetProtocolSink_ReportProgress(binding_sink,
3585 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
3586 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
3588 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
3589 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
3591 hres = IInternetProtocolSink_ReportData(binding_sink, 0, 0, 0);
3592 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
3594 IInternetProtocolSink_Release(binding_sink);
3595 IInternetPriority_Release(priority);
3596 IInternetBindInfo_Release(prot_bind_info);
3597 IInternetProtocol_Release(protocol);
3599 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3600 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3601 ok(protocol != NULL, "protocol == NULL\n");
3603 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3604 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3606 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
3607 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3609 IInternetProtocol_Release(protocol);
3611 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, wsz_test);
3612 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3614 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3615 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3616 ok(protocol != NULL, "protocol == NULL\n");
3618 SET_EXPECT(QueryService_InternetProtocol);
3619 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3620 ok(hres == MK_E_SYNTAX, "Start failed: %08x, expected MK_E_SYNTAX\n", hres);
3621 CHECK_CALLED(QueryService_InternetProtocol);
3623 IInternetProtocol_Release(protocol);
3625 IInternetSession_Release(session);
3628 static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
3630 IInternetProtocolEx *protocolex = NULL;
3631 IInternetProtocol *protocol;
3632 IInternetSession *session;
3633 IUri *uri = NULL;
3634 ULONG ref;
3635 HRESULT hres;
3637 pi = grf_pi;
3639 init_test(prot, test_flags|TEST_BINDING);
3641 hres = pCoInternetGetSession(0, &session, 0);
3642 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3644 if(test_flags & TEST_EMULATEPROT) {
3645 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
3646 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3649 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
3650 binding_protocol = protocol;
3651 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3652 ok(protocol != NULL, "protocol == NULL\n");
3654 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3655 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3657 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3658 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
3660 if(test_flags & TEST_USEIURI) {
3661 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3662 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3664 hres = pCreateUri(binding_urls[prot], Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
3665 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3668 ex_priority = 0;
3669 SET_EXPECT(QueryService_InternetProtocol);
3670 SET_EXPECT(CreateInstance);
3671 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3672 SET_EXPECT(SetPriority);
3673 if(impl_protex)
3674 SET_EXPECT(StartEx);
3675 else
3676 SET_EXPECT(Start);
3678 expect_hrResult = S_OK;
3680 if(protocolex) {
3681 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, pi, 0);
3682 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
3683 }else {
3684 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0);
3685 ok(hres == S_OK, "Start failed: %08x\n", hres);
3688 CHECK_CALLED(QueryService_InternetProtocol);
3689 CHECK_CALLED(CreateInstance);
3690 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3691 CLEAR_CALLED(SetPriority); /* IE11 does not call it. */
3692 if(impl_protex)
3693 CHECK_CALLED(StartEx);
3694 else
3695 CHECK_CALLED(Start);
3697 if(protocolex)
3698 IInternetProtocolEx_Release(protocolex);
3699 if(uri)
3700 IUri_Release(uri);
3702 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
3703 while(prot_state < 4) {
3704 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3705 if(mimefilter_test && filtered_protocol) {
3706 SET_EXPECT(Continue);
3707 IInternetProtocol_Continue(filtered_protocol, pdata);
3708 CHECK_CALLED(Continue);
3709 }else {
3710 SET_EXPECT(Continue);
3711 IInternetProtocol_Continue(protocol, pdata);
3712 CHECK_CALLED(Continue);
3714 if(test_abort && prot_state == 2) {
3715 SET_EXPECT(Abort);
3716 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3717 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3718 CHECK_CALLED(Abort);
3720 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3721 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3722 SetEvent(event_complete2);
3723 break;
3725 SetEvent(event_complete2);
3727 if(direct_read)
3728 CHECK_CALLED(ReportData); /* Set in ReportResult */
3729 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3730 }else {
3731 if(mimefilter_test)
3732 SET_EXPECT(MimeFilter_LockRequest);
3733 else
3734 SET_EXPECT(LockRequest);
3735 hres = IInternetProtocol_LockRequest(protocol, 0);
3736 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3737 if(mimefilter_test)
3738 CHECK_CALLED(MimeFilter_LockRequest);
3739 else
3740 CHECK_CALLED(LockRequest);
3742 if(mimefilter_test)
3743 SET_EXPECT(MimeFilter_UnlockRequest);
3744 else
3745 SET_EXPECT(UnlockRequest);
3746 hres = IInternetProtocol_UnlockRequest(protocol);
3747 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3748 if(mimefilter_test)
3749 CHECK_CALLED(MimeFilter_UnlockRequest);
3750 else
3751 CHECK_CALLED(UnlockRequest);
3754 if(mimefilter_test)
3755 SET_EXPECT(MimeFilter_Terminate);
3756 else
3757 SET_EXPECT(Terminate);
3758 hres = IInternetProtocol_Terminate(protocol, 0);
3759 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3760 if(mimefilter_test)
3761 CLEAR_CALLED(MimeFilter_Terminate);
3762 else
3763 CHECK_CALLED(Terminate);
3765 if(filtered_protocol)
3766 IInternetProtocol_Release(filtered_protocol);
3767 IInternetBindInfo_Release(prot_bind_info);
3768 IInternetProtocolSink_Release(binding_sink);
3769 ref = IInternetProtocol_Release(protocol);
3770 ok(!ref, "ref=%u, expected 0\n", ref);
3772 if(test_flags & TEST_EMULATEPROT) {
3773 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]);
3774 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3777 IInternetSession_Release(session);
3780 START_TEST(protocol)
3782 HMODULE hurlmon;
3784 hurlmon = GetModuleHandleA("urlmon.dll");
3785 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
3786 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
3787 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3789 if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3790 win_skip("Various needed functions not present, too old IE\n");
3791 return;
3794 if(!pCreateUri)
3795 win_skip("CreateUri not supported\n");
3797 OleInitialize(NULL);
3799 event_complete = CreateEventW(NULL, FALSE, FALSE, NULL);
3800 event_complete2 = CreateEventW(NULL, FALSE, FALSE, NULL);
3801 event_continue = CreateEventW(NULL, FALSE, FALSE, NULL);
3802 event_continue_done = CreateEventW(NULL, FALSE, FALSE, NULL);
3803 thread_id = GetCurrentThreadId();
3805 test_file_protocol();
3806 test_http_protocol();
3807 if(pCreateUri)
3808 test_https_protocol();
3809 else
3810 win_skip("Skipping https tests on too old platform\n");
3811 test_ftp_protocol();
3812 test_gopher_protocol();
3813 test_mk_protocol();
3814 test_CreateBinding();
3816 bindf &= ~BINDF_FROMURLMON;
3817 trace("Testing file binding (mime verification, emulate prot)...\n");
3818 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3819 trace("Testing http binding (mime verification, emulate prot)...\n");
3820 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3821 trace("Testing its binding (mime verification, emulate prot)...\n");
3822 test_binding(ITS_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3823 trace("Testing http binding (mime verification, emulate prot, short read, direct read)...\n");
3824 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_SHORT_READ|TEST_DIRECT_READ);
3825 trace("Testing file binding (mime verification, emulate prot, mime filter)...\n");
3826 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3827 trace("Testing http binding (mime verification, emulate prot, mime filter)...\n");
3828 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3829 trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n");
3830 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME);
3831 trace("Testing http binding (mime verification, emulate prot, direct read)...\n");
3832 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
3833 trace("Testing http binding (mime verification, emulate prot, abort)...\n");
3834 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
3835 if(pCreateUri) {
3836 trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
3837 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);
3838 trace("Testing file binding (use IUri, impl StartEx, mime verification, emulate prot)...\n");
3839 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI|TEST_IMPLPROTEX);
3840 trace("Testing file binding (impl StartEx, mime verification, emulate prot)...\n");
3841 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_IMPLPROTEX);
3844 CloseHandle(event_complete);
3845 CloseHandle(event_complete2);
3846 CloseHandle(event_continue);
3847 CloseHandle(event_continue_done);
3849 OleUninitialize();