urlmon/tests: Allow QueryInterface to accept IUnknown and IInternetProtocolSink.
[wine.git] / dlls / urlmon / tests / protocol.c
blob5981c25c8d48446c89644a37622abfb26e6a188e
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 if(IsEqualGUID(&IID_IUnknown, riid)
1114 || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
1115 *ppv = iface;
1116 return S_OK;
1119 ok(0, "unexpected call\n");
1120 return E_NOTIMPL;
1123 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1125 return 2;
1128 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1130 return 1;
1133 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1135 HRESULT hres;
1137 CHECK_EXPECT(MimeFilter_Switch);
1139 SET_EXPECT(Switch);
1140 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1141 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1142 CHECK_CALLED(Switch);
1144 return S_OK;
1147 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1148 LPCWSTR szStatusText)
1150 switch(ulStatusCode) {
1151 case BINDSTATUS_LOADINGMIMEHANDLER:
1153 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1154 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1155 * ProtocolSink_ReportProgress to workaround it.
1157 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1158 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1159 break;
1160 default:
1161 ok(0, "Unexpected status code %d\n", ulStatusCode);
1164 return S_OK;
1167 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1168 ULONG ulProgress, ULONG ulProgressMax)
1170 DWORD read = 0;
1171 BYTE buf[8192];
1172 HRESULT hres;
1173 BOOL report_mime = FALSE;
1175 CHECK_EXPECT(MimeFilter_ReportData);
1177 if(!filter_state && !no_mime) {
1178 SET_EXPECT(Read);
1179 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1180 if(tested_protocol == HTTP_TEST)
1181 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1182 else
1183 ok(hres == S_OK, "Read failed: %08x\n", hres);
1184 CHECK_CALLED(Read);
1186 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1187 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1188 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1189 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1191 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1192 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1193 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1194 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1196 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1199 if(no_mime && prot_read<200) {
1200 SET_EXPECT(Read);
1201 }else if(no_mime && prot_read<300) {
1202 report_mime = TRUE;
1203 SET_EXPECT(Read);
1204 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1205 SET_EXPECT(ReportData);
1206 }else if(!read_report_data) {
1207 SET_EXPECT(ReportData);
1209 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1210 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1211 if(no_mime && prot_read<=200) {
1212 CHECK_CALLED(Read);
1213 }else if(report_mime) {
1214 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1215 CHECK_CALLED(ReportData);
1216 }else if(!read_report_data) {
1217 CHECK_CALLED(ReportData);
1220 if(!filter_state)
1221 filter_state = 1;
1223 return S_OK;
1226 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1227 DWORD dwError, LPCWSTR szResult)
1229 HRESULT hres;
1231 CHECK_EXPECT(MimeFilter_ReportResult);
1233 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1234 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1235 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1237 SET_EXPECT(ReportResult);
1238 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1239 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1240 CHECK_CALLED(ReportResult);
1242 return S_OK;
1245 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1246 MimeProtocolSink_QueryInterface,
1247 MimeProtocolSink_AddRef,
1248 MimeProtocolSink_Release,
1249 MimeProtocolSink_Switch,
1250 MimeProtocolSink_ReportProgress,
1251 MimeProtocolSink_ReportData,
1252 MimeProtocolSink_ReportResult
1255 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1257 static HRESULT QueryInterface(REFIID riid, void **ppv)
1259 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1260 static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1262 *ppv = NULL;
1264 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1265 *ppv = &protocol_sink;
1266 if(IsEqualGUID(&IID_IServiceProvider, riid))
1267 *ppv = &service_provider;
1268 if(IsEqualGUID(&IID_IUriContainer, riid))
1269 return E_NOINTERFACE; /* TODO */
1271 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1272 if(IsEqualGUID(&IID_undocumented, riid))
1273 return E_NOINTERFACE;
1274 /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1275 if(IsEqualGUID(&IID_undocumentedIE10, riid))
1276 return E_NOINTERFACE;
1278 if(*ppv)
1279 return S_OK;
1281 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1282 return E_NOINTERFACE;
1285 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1287 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1288 *ppv = iface;
1289 return S_OK;
1291 return E_NOINTERFACE;
1294 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1296 return 2;
1299 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1301 return 1;
1304 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1306 DWORD cbSize;
1308 CHECK_EXPECT(GetBindInfo);
1310 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1311 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1312 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1314 *grfBINDF = bindf;
1315 if(binding_test)
1316 *grfBINDF |= BINDF_FROMURLMON;
1317 cbSize = pbindinfo->cbSize;
1318 memset(pbindinfo, 0, cbSize);
1319 pbindinfo->cbSize = cbSize;
1321 if(http_post_test)
1323 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1324 pbindinfo->dwBindVerb = BINDVERB_POST;
1325 pbindinfo->stgmedData.tymed = http_post_test;
1327 if(http_post_test == TYMED_HGLOBAL) {
1328 HGLOBAL data;
1330 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1331 data = GlobalAlloc(GPTR, sizeof(post_data));
1332 memcpy(data, post_data, sizeof(post_data));
1333 U(pbindinfo->stgmedData).hGlobal = data;
1334 }else {
1335 IStream *post_stream;
1336 HGLOBAL data;
1337 HRESULT hres;
1339 if(0) {
1340 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1341 data = GlobalAlloc(GPTR, sizeof(post_data));
1342 memcpy(data, post_data, sizeof(post_data));
1343 U(pbindinfo->stgmedData).hGlobal = data;
1345 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1346 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1348 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1350 U(pbindinfo->stgmedData).pstm = &Stream;
1354 return S_OK;
1357 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1358 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1360 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1361 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1363 switch(ulStringType) {
1364 case BINDSTRING_ACCEPT_MIMES:
1365 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1366 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1367 if(pcElFetched) {
1368 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1369 *pcElFetched = 1;
1371 if(ppwzStr) {
1372 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1373 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1375 return S_OK;
1376 case BINDSTRING_USER_AGENT:
1377 CHECK_EXPECT(GetBindString_USER_AGENT);
1378 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1379 if(pcElFetched) {
1380 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1381 *pcElFetched = 1;
1383 if(ppwzStr) {
1384 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1385 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1387 return S_OK;
1388 case BINDSTRING_POST_COOKIE:
1389 CHECK_EXPECT(GetBindString_POST_COOKIE);
1390 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1391 if(pcElFetched)
1392 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1393 return S_OK;
1394 case BINDSTRING_URL: {
1395 DWORD size;
1397 CHECK_EXPECT(GetBindString_URL);
1398 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1399 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1400 *pcElFetched = 1;
1402 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1403 *ppwzStr = CoTaskMemAlloc(size);
1404 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1405 return S_OK;
1407 case BINDSTRING_ROOTDOC_URL:
1408 CHECK_EXPECT(GetBindString_ROOTDOC_URL);
1409 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1410 return E_NOTIMPL;
1411 case BINDSTRING_ENTERPRISE_ID:
1412 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1413 return E_NOTIMPL;
1414 default:
1415 ok(0, "unexpected ulStringType %d\n", ulStringType);
1418 return E_NOTIMPL;
1421 static IInternetBindInfoVtbl bind_info_vtbl = {
1422 BindInfo_QueryInterface,
1423 BindInfo_AddRef,
1424 BindInfo_Release,
1425 BindInfo_GetBindInfo,
1426 BindInfo_GetBindString
1429 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1431 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1432 REFIID riid, void **ppv)
1434 ok(0, "unexpected call\n");
1435 return E_NOINTERFACE;
1438 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1440 return 2;
1443 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1445 return 1;
1448 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1450 CHECK_EXPECT(SetPriority);
1451 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1452 return S_OK;
1455 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1457 ok(0, "unexpected call\n");
1458 return E_NOTIMPL;
1462 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1463 InternetPriority_QueryInterface,
1464 InternetPriority_AddRef,
1465 InternetPriority_Release,
1466 InternetPriority_SetPriority,
1467 InternetPriority_GetPriority
1470 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1472 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1474 return 2;
1477 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1479 return 1;
1482 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1483 DWORD dwOptions)
1485 HRESULT hres;
1487 CHECK_EXPECT(Abort);
1489 SET_EXPECT(ReportResult);
1490 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1491 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1492 CHECK_CALLED(ReportResult);
1494 return S_OK;
1497 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1499 ok(0, "unexpected call\n");
1500 return E_NOTIMPL;
1503 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1505 ok(0, "unexpected call\n");
1506 return E_NOTIMPL;
1509 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1510 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1512 ok(0, "unexpected call\n");
1513 return E_NOTIMPL;
1516 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1518 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1520 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1521 *ppv = iface;
1522 return S_OK;
1525 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1526 if(impl_protex) {
1527 *ppv = iface;
1528 return S_OK;
1530 *ppv = NULL;
1531 return E_NOINTERFACE;
1534 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1535 *ppv = &InternetPriority;
1536 return S_OK;
1539 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1540 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1541 *ppv = NULL;
1542 return E_NOINTERFACE;
1545 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1546 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1547 *ppv = NULL;
1548 return E_NOINTERFACE;
1551 if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */
1552 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1553 *ppv = NULL;
1554 return E_NOINTERFACE;
1557 static DWORD WINAPI thread_proc(PVOID arg)
1559 HRESULT hres;
1561 memset(&protocoldata, -1, sizeof(protocoldata));
1563 prot_state = 0;
1565 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1566 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1567 BINDSTATUS_FINDINGRESOURCE, hostW);
1568 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1569 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1571 SET_EXPECT(ReportProgress_CONNECTING);
1572 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1573 BINDSTATUS_CONNECTING, winehq_ipW);
1574 CHECK_CALLED(ReportProgress_CONNECTING);
1575 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1577 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1578 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1579 BINDSTATUS_SENDINGREQUEST, NULL);
1580 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1581 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1583 prot_state = 1;
1584 SET_EXPECT(Switch);
1585 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1586 CHECK_CALLED(Switch);
1587 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1589 if(!short_read) {
1590 prot_state = 2;
1591 if(mimefilter_test)
1592 SET_EXPECT(MimeFilter_Switch);
1593 else
1594 SET_EXPECT(Switch);
1595 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1596 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1597 if(mimefilter_test)
1598 CHECK_CALLED(MimeFilter_Switch);
1599 else
1600 CHECK_CALLED(Switch);
1602 if(test_abort) {
1603 SetEvent(event_complete);
1604 return 0;
1607 prot_state = 2;
1608 if(mimefilter_test)
1609 SET_EXPECT(MimeFilter_Switch);
1610 else
1611 SET_EXPECT(Switch);
1612 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1613 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1614 if(mimefilter_test)
1615 CHECK_CALLED(MimeFilter_Switch);
1616 else
1617 CHECK_CALLED(Switch);
1619 prot_state = 3;
1620 if(mimefilter_test)
1621 SET_EXPECT(MimeFilter_Switch);
1622 else
1623 SET_EXPECT(Switch);
1624 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1625 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1626 if(mimefilter_test)
1627 CHECK_CALLED(MimeFilter_Switch);
1628 else
1629 CHECK_CALLED(Switch);
1632 SetEvent(event_complete);
1634 return 0;
1637 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1639 BINDINFO bindinfo, exp_bindinfo;
1640 DWORD cbindf = 0;
1641 HRESULT hres;
1643 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1644 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1645 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1646 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1647 ok(!pi, "pi = %x\n", pi);
1649 if(binding_test)
1650 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1652 memset(&bindinfo, 0, sizeof(bindinfo));
1653 bindinfo.cbSize = sizeof(bindinfo);
1654 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1655 SET_EXPECT(GetBindInfo);
1656 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1657 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1658 CHECK_CALLED(GetBindInfo);
1659 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1660 cbindf, (bindf|BINDF_FROMURLMON));
1661 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1662 pReleaseBindInfo(&bindinfo);
1664 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1665 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1666 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1667 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1669 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1670 IServiceProvider *service_provider;
1671 IHttpNegotiate *http_negotiate;
1672 IHttpNegotiate2 *http_negotiate2;
1673 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1674 LPWSTR additional_headers = NULL;
1675 BYTE sec_id[100];
1676 DWORD fetched = 0, size = 100;
1677 DWORD tid;
1679 SET_EXPECT(GetBindString_USER_AGENT);
1680 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1681 &ua, 1, &fetched);
1682 CHECK_CALLED(GetBindString_USER_AGENT);
1683 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1684 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1685 ok(ua != NULL, "ua = %p\n", ua);
1686 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1687 CoTaskMemFree(ua);
1689 fetched = 256;
1690 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1691 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1692 accept_mimes, 256, &fetched);
1693 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1695 ok(hres == S_OK,
1696 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1697 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1698 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1699 CoTaskMemFree(accept_mimes[0]);
1701 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1702 (void**)&service_provider);
1703 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1705 SET_EXPECT(QueryService_HttpNegotiate);
1706 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1707 &IID_IHttpNegotiate, (void**)&http_negotiate);
1708 CHECK_CALLED(QueryService_HttpNegotiate);
1709 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1711 SET_EXPECT(BeginningTransaction);
1712 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1713 NULL, 0, &additional_headers);
1714 CHECK_CALLED(BeginningTransaction);
1715 IHttpNegotiate_Release(http_negotiate);
1716 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1717 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1719 SET_EXPECT(QueryService_HttpNegotiate);
1720 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1721 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1722 CHECK_CALLED(QueryService_HttpNegotiate);
1723 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1725 size = 512;
1726 SET_EXPECT(GetRootSecurityId);
1727 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1728 CHECK_CALLED(GetRootSecurityId);
1729 IHttpNegotiate2_Release(http_negotiate2);
1730 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1731 ok(size == 13, "size=%d\n", size);
1733 IServiceProvider_Release(service_provider);
1735 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1736 return;
1739 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1740 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1741 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1742 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1743 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1745 if(mimefilter_test) {
1746 SET_EXPECT(MimeFilter_CreateInstance);
1747 SET_EXPECT(MimeFilter_Start);
1748 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1750 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1751 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1752 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1753 ok(hres == S_OK,
1754 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1755 if(mimefilter_test) {
1756 CHECK_CALLED(MimeFilter_CreateInstance);
1757 CHECK_CALLED(MimeFilter_Start);
1758 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1759 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1760 }else {
1761 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1764 if(mimefilter_test)
1765 SET_EXPECT(MimeFilter_ReportData);
1766 else
1767 SET_EXPECT(ReportData);
1768 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1769 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1770 13, 13);
1771 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1772 if(mimefilter_test)
1773 CHECK_CALLED(MimeFilter_ReportData);
1774 else
1775 CHECK_CALLED(ReportData);
1777 if(tested_protocol == ITS_TEST) {
1778 SET_EXPECT(ReportData);
1779 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1780 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1781 CHECK_CALLED(ReportData);
1784 if(tested_protocol == BIND_TEST) {
1785 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1786 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1789 if(mimefilter_test)
1790 SET_EXPECT(MimeFilter_ReportResult);
1791 else
1792 SET_EXPECT(ReportResult);
1793 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1794 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1795 if(mimefilter_test)
1796 CHECK_CALLED(MimeFilter_ReportResult);
1797 else
1798 CHECK_CALLED(ReportResult);
1801 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1802 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1803 DWORD grfPI, HANDLE_PTR dwReserved)
1805 CHECK_EXPECT(Start);
1807 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1808 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1809 return S_OK;
1812 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1813 PROTOCOLDATA *pProtocolData)
1815 DWORD bscf = 0, pr;
1816 HRESULT hres;
1818 CHECK_EXPECT(Continue);
1820 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1821 if(!pProtocolData || tested_protocol == BIND_TEST)
1822 return S_OK;
1823 if(binding_test) {
1824 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1825 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1826 pProtocolData->grfFlags, protocoldata.grfFlags );
1827 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1828 pProtocolData->dwState, protocoldata.dwState );
1829 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1830 pProtocolData->pData, protocoldata.pData );
1831 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1832 pProtocolData->cbData, protocoldata.cbData );
1835 switch(prot_state) {
1836 case 1: {
1837 IServiceProvider *service_provider;
1838 IHttpNegotiate *http_negotiate;
1839 static const WCHAR header[] = {'?',0};
1841 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1842 (void**)&service_provider);
1843 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1845 SET_EXPECT(QueryService_HttpNegotiate);
1846 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1847 &IID_IHttpNegotiate, (void**)&http_negotiate);
1848 IServiceProvider_Release(service_provider);
1849 CHECK_CALLED(QueryService_HttpNegotiate);
1850 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1852 SET_EXPECT(OnResponse);
1853 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1854 IHttpNegotiate_Release(http_negotiate);
1855 CHECK_CALLED(OnResponse);
1856 IHttpNegotiate_Release(http_negotiate);
1857 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1859 if(mimefilter_test) {
1860 SET_EXPECT(MimeFilter_CreateInstance);
1861 SET_EXPECT(MimeFilter_Start);
1862 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1863 }else if(!(pi & PI_MIMEVERIFICATION)) {
1864 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1866 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1867 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1868 if(mimefilter_test) {
1869 CHECK_CALLED(MimeFilter_CreateInstance);
1870 CHECK_CALLED(MimeFilter_Start);
1871 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1872 }else if(!(pi & PI_MIMEVERIFICATION)) {
1873 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1875 ok(hres == S_OK,
1876 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1878 bscf |= BSCF_FIRSTDATANOTIFICATION;
1879 break;
1881 case 2:
1882 case 3:
1883 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1884 break;
1887 pr = prot_read;
1888 if(mimefilter_test)
1889 SET_EXPECT(MimeFilter_ReportData);
1890 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1891 if(pr < 200)
1892 SET_EXPECT(Read); /* checked in ReportData for short_read */
1893 if(pr == 200) {
1894 if(!mimefilter_test)
1895 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1896 SET_EXPECT(GetBindInfo);
1897 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1899 if(pr >= 200)
1900 SET_EXPECT(ReportData);
1901 }else {
1902 SET_EXPECT(ReportData);
1905 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1906 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1908 if(mimefilter_test) {
1909 SET_EXPECT(MimeFilter_ReportData);
1910 }else if(pi & PI_MIMEVERIFICATION) {
1911 if(!short_read && pr < 200)
1912 CHECK_CALLED(Read);
1913 if(pr == 200) {
1914 CLEAR_CALLED(GetBindInfo); /* IE9 */
1915 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1917 }else {
1918 CHECK_CALLED(ReportData);
1921 if(prot_state == 3)
1922 prot_state = 4;
1924 return S_OK;
1927 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1929 CHECK_EXPECT(Terminate);
1930 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1931 return S_OK;
1934 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1935 ULONG cb, ULONG *pcbRead)
1937 if(read_report_data)
1938 CHECK_EXPECT2(Read2);
1940 if(mimefilter_test || short_read) {
1941 if(!read_report_data)
1942 CHECK_EXPECT2(Read);
1943 }else if((pi & PI_MIMEVERIFICATION)) {
1944 if(!read_report_data)
1945 CHECK_EXPECT2(Read);
1947 if(prot_read < 300) {
1948 ok(pv != expect_pv, "pv == expect_pv\n");
1949 if(prot_read < 300)
1950 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1951 else
1952 ok(cb == 700, "cb=%d\n", cb);
1953 }else {
1954 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1956 }else {
1957 if(!read_report_data)
1958 CHECK_EXPECT(Read);
1960 ok(pv == expect_pv, "pv != expect_pv\n");
1961 ok(cb == 1000, "cb=%d\n", cb);
1962 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1964 ok(pcbRead != NULL, "pcbRead == NULL\n");
1966 if(prot_state == 3 || (short_read && prot_state != 4)) {
1967 HRESULT hres;
1969 prot_state = 4;
1970 if(short_read) {
1971 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1972 SET_EXPECT(GetBindInfo);
1973 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1975 if(mimefilter_test)
1976 SET_EXPECT(MimeFilter_ReportData);
1977 else if(direct_read)
1978 SET_EXPECT(ReportData2);
1979 read_report_data++;
1980 hres = IInternetProtocolSink_ReportData(binding_sink,
1981 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1982 read_report_data--;
1983 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1984 if(short_read) {
1985 CLEAR_CALLED(GetBindInfo); /* IE9 */
1986 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1988 if(mimefilter_test)
1989 CHECK_CALLED(MimeFilter_ReportData);
1990 else if(direct_read)
1991 CHECK_CALLED(ReportData2);
1993 if(mimefilter_test)
1994 SET_EXPECT(MimeFilter_ReportResult);
1995 else
1996 SET_EXPECT(ReportResult);
1997 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1998 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1999 if(mimefilter_test)
2000 CHECK_CALLED(MimeFilter_ReportResult);
2001 else
2002 CHECK_CALLED(ReportResult);
2004 if(cb > 100)
2005 cb = 100;
2006 memset(pv, 'x', cb);
2007 if(cb>6)
2008 memcpy(pv, "gif87a", 6);
2009 prot_read += *pcbRead = cb;
2010 return S_OK;
2013 if(prot_state == 4) {
2014 *pcbRead = 0;
2015 return S_FALSE;
2018 if((async_read_pending = !async_read_pending)) {
2019 *pcbRead = 0;
2020 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
2023 if(cb > 100)
2024 cb = 100;
2025 memset(pv, 'x', cb);
2026 if(cb>6)
2027 memcpy(pv, "gif87a", 6);
2028 prot_read += *pcbRead = cb;
2029 return S_OK;
2032 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2034 CHECK_EXPECT(LockRequest);
2035 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2036 return S_OK;
2039 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2041 CHECK_EXPECT(UnlockRequest);
2042 return S_OK;
2045 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2046 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2047 DWORD grfPI, HANDLE *dwReserved)
2049 CHECK_EXPECT(StartEx);
2050 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2051 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2052 return S_OK;
2055 static const IInternetProtocolExVtbl ProtocolVtbl = {
2056 ProtocolEmul_QueryInterface,
2057 Protocol_AddRef,
2058 Protocol_Release,
2059 ProtocolEmul_Start,
2060 ProtocolEmul_Continue,
2061 Protocol_Abort,
2062 ProtocolEmul_Terminate,
2063 Protocol_Suspend,
2064 Protocol_Resume,
2065 ProtocolEmul_Read,
2066 Protocol_Seek,
2067 ProtocolEmul_LockRequest,
2068 ProtocolEmul_UnlockRequest,
2069 ProtocolEmul_StartEx
2072 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2074 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2076 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2077 *ppv = iface;
2078 return S_OK;
2081 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2082 *ppv = &mime_protocol_sink;
2083 return S_OK;
2086 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2087 *ppv = NULL;
2088 return E_NOINTERFACE;
2091 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2092 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2093 DWORD grfPI, HANDLE_PTR dwReserved)
2095 PROTOCOLFILTERDATA *data;
2096 LPOLESTR url_str = NULL;
2097 DWORD fetched = 0;
2098 BINDINFO bindinfo;
2099 DWORD cbindf = 0;
2100 HRESULT hres;
2102 CHECK_EXPECT(MimeFilter_Start);
2104 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2105 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2106 ok(dwReserved, "dwReserved == 0\n");
2107 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2108 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2110 if(binding_test) {
2111 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2112 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2113 }else {
2114 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2115 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2118 data = (void*)dwReserved;
2119 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2120 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2121 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2122 ok(!data->pUnk, "data->pUnk != NULL\n");
2123 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2124 if(binding_test) {
2125 IInternetProtocolSink *prot_sink;
2127 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2128 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2129 IInternetProtocolSink_Release(prot_sink);
2131 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2133 filtered_protocol = data->pProtocol;
2134 IInternetProtocol_AddRef(filtered_protocol);
2135 }else {
2136 IInternetProtocol *prot;
2138 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2139 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2140 IInternetProtocol_Release(prot);
2142 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2145 filtered_sink = pOIProtSink;
2147 SET_EXPECT(ReportProgress_DECODING);
2148 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2149 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2150 CHECK_CALLED(ReportProgress_DECODING);
2152 SET_EXPECT(GetBindInfo);
2153 memset(&bindinfo, 0, sizeof(bindinfo));
2154 bindinfo.cbSize = sizeof(bindinfo);
2155 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2156 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2157 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2158 CHECK_CALLED(GetBindInfo);
2160 SET_EXPECT(GetBindString_URL);
2161 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2162 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2163 ok(fetched == 1, "fetched = %d\n", fetched);
2164 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2165 CoTaskMemFree(url_str);
2166 CHECK_CALLED(GetBindString_URL);
2168 return S_OK;
2171 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2172 PROTOCOLDATA *pProtocolData)
2174 CHECK_EXPECT(MimeFilter_Continue);
2175 return E_NOTIMPL;
2178 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2180 HRESULT hres;
2182 CHECK_EXPECT(MimeFilter_Terminate);
2184 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2186 SET_EXPECT(Terminate);
2187 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2188 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2189 CHECK_CALLED(Terminate);
2191 return S_OK;
2194 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2195 ULONG cb, ULONG *pcbRead)
2197 BYTE buf[2096];
2198 DWORD read = 0;
2199 HRESULT hres;
2201 CHECK_EXPECT(MimeFilter_Read);
2203 ok(pv != NULL, "pv == NULL\n");
2204 ok(cb != 0, "cb == 0\n");
2205 ok(pcbRead != NULL, "pcbRead == NULL\n");
2207 if(read_report_data)
2208 SET_EXPECT(Read2);
2209 else
2210 SET_EXPECT(Read);
2211 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2212 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2213 if(read_report_data)
2214 CHECK_CALLED(Read2);
2215 else
2216 CHECK_CALLED(Read);
2218 if(pcbRead) {
2219 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2220 *pcbRead = read;
2223 memset(pv, 'x', read);
2224 return hres;
2227 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2229 HRESULT hres;
2231 CHECK_EXPECT(MimeFilter_LockRequest);
2233 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2235 SET_EXPECT(LockRequest);
2236 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2237 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2238 CHECK_CALLED(LockRequest);
2240 return S_OK;
2243 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2245 HRESULT hres;
2247 CHECK_EXPECT(MimeFilter_UnlockRequest);
2249 SET_EXPECT(UnlockRequest);
2250 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2251 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2252 CHECK_CALLED(UnlockRequest);
2254 return S_OK;
2257 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2258 MimeProtocol_QueryInterface,
2259 Protocol_AddRef,
2260 Protocol_Release,
2261 MimeProtocol_Start,
2262 Protocol_Continue,
2263 Protocol_Abort,
2264 MimeProtocol_Terminate,
2265 Protocol_Suspend,
2266 Protocol_Resume,
2267 MimeProtocol_Read,
2268 Protocol_Seek,
2269 MimeProtocol_LockRequest,
2270 MimeProtocol_UnlockRequest
2273 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2275 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2277 ok(0, "unexpected call\n");
2278 return E_NOINTERFACE;
2281 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2283 return 2;
2286 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2288 return 1;
2291 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2292 REFIID riid, void **ppv)
2294 CHECK_EXPECT(CreateInstance);
2296 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2297 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2298 ok(ppv != NULL, "ppv == NULL\n");
2300 *ppv = &Protocol;
2301 return S_OK;
2304 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2306 ok(0, "unexpected call\n");
2307 return S_OK;
2310 static const IClassFactoryVtbl ClassFactoryVtbl = {
2311 ClassFactory_QueryInterface,
2312 ClassFactory_AddRef,
2313 ClassFactory_Release,
2314 ClassFactory_CreateInstance,
2315 ClassFactory_LockServer
2318 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2320 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2322 CHECK_EXPECT(MimeFilter_CreateInstance);
2324 ok(!outer, "outer = %p\n", outer);
2325 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2327 *ppv = &MimeProtocol;
2328 return S_OK;
2331 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2332 ClassFactory_QueryInterface,
2333 ClassFactory_AddRef,
2334 ClassFactory_Release,
2335 MimeFilter_CreateInstance,
2336 ClassFactory_LockServer
2339 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2341 #define TEST_BINDING 0x0001
2342 #define TEST_FILTER 0x0002
2343 #define TEST_FIRST_HTTP 0x0004
2344 #define TEST_DIRECT_READ 0x0008
2345 #define TEST_POST 0x0010
2346 #define TEST_EMULATEPROT 0x0020
2347 #define TEST_SHORT_READ 0x0040
2348 #define TEST_REDIRECT 0x0080
2349 #define TEST_ABORT 0x0100
2350 #define TEST_ASYNCREQ 0x0200
2351 #define TEST_USEIURI 0x0400
2352 #define TEST_IMPLPROTEX 0x0800
2353 #define TEST_EMPTY 0x1000
2354 #define TEST_NOMIME 0x2000
2355 #define TEST_FROMCACHE 0x4000
2357 static void register_filter(BOOL do_register)
2359 IInternetSession *session;
2360 HRESULT hres;
2362 hres = pCoInternetGetSession(0, &session, 0);
2363 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2365 if(do_register) {
2366 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2367 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2368 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2369 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2370 }else {
2371 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2372 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2373 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2374 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2377 IInternetSession_Release(session);
2380 static void init_test(int prot, DWORD flags)
2382 tested_protocol = prot;
2383 binding_test = (flags & TEST_BINDING) != 0;
2384 first_data_notif = TRUE;
2385 prot_read = 0;
2386 prot_state = 0;
2387 async_read_pending = TRUE;
2388 mimefilter_test = (flags & TEST_FILTER) != 0;
2389 no_mime = (flags & TEST_NOMIME) != 0;
2390 filter_state = 0;
2391 post_stream_read = 0;
2392 ResetEvent(event_complete);
2393 ResetEvent(event_complete2);
2394 ResetEvent(event_continue);
2395 ResetEvent(event_continue_done);
2396 async_protocol = binding_protocol = filtered_protocol = NULL;
2397 filtered_sink = NULL;
2398 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2399 first_data_notif = TRUE;
2400 state = STATE_CONNECTING;
2401 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2402 direct_read = (flags & TEST_DIRECT_READ) != 0;
2403 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2404 wait_for_switch = TRUE;
2405 short_read = (flags & TEST_SHORT_READ) != 0;
2406 http_post_test = TYMED_NULL;
2407 test_redirect = (flags & TEST_REDIRECT) != 0;
2408 test_abort = (flags & TEST_ABORT) != 0;
2409 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2410 empty_file = (flags & TEST_EMPTY) != 0;
2411 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2412 file_with_hash = FALSE;
2414 register_filter(mimefilter_test);
2417 static void test_priority(IInternetProtocol *protocol)
2419 IInternetPriority *priority;
2420 LONG pr;
2421 HRESULT hres;
2423 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2424 (void**)&priority);
2425 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2426 if(FAILED(hres))
2427 return;
2429 hres = IInternetPriority_GetPriority(priority, &pr);
2430 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2431 ok(pr == 0, "pr=%d, expected 0\n", pr);
2433 hres = IInternetPriority_SetPriority(priority, 1);
2434 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2436 hres = IInternetPriority_GetPriority(priority, &pr);
2437 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2438 ok(pr == 1, "pr=%d, expected 1\n", pr);
2440 IInternetPriority_Release(priority);
2443 static void test_early_abort(const CLSID *clsid)
2445 IInternetProtocol *protocol;
2446 HRESULT hres;
2448 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2449 &IID_IInternetProtocol, (void**)&protocol);
2450 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2452 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2453 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2455 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2456 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2458 IInternetProtocol_Release(protocol);
2461 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2462 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2464 HRESULT hres;
2466 SET_EXPECT(GetBindInfo);
2467 if(!(bindf & BINDF_FROMURLMON))
2468 SET_EXPECT(ReportProgress_DIRECTBIND);
2469 if(is_first) {
2470 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2471 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2472 if(bindf & BINDF_FROMURLMON)
2473 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2474 else
2475 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2477 SET_EXPECT(ReportData);
2478 if(is_first)
2479 SET_EXPECT(ReportResult);
2481 expect_hrResult = S_OK;
2483 if(protocolex) {
2484 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2485 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2486 }else {
2487 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2488 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2489 win_skip("Start failed\n");
2490 return FALSE;
2492 ok(hres == S_OK, "Start failed: %08x\n", hres);
2495 CHECK_CALLED(GetBindInfo);
2496 if(!(bindf & BINDF_FROMURLMON))
2497 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2498 if(is_first) {
2499 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2500 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2501 if(bindf & BINDF_FROMURLMON)
2502 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2503 else
2504 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2506 CHECK_CALLED(ReportData);
2507 if(is_first)
2508 CHECK_CALLED(ReportResult);
2510 return TRUE;
2513 static void test_file_protocol_url(LPCWSTR url)
2515 IInternetProtocolInfo *protocol_info;
2516 IUnknown *unk;
2517 IClassFactory *factory;
2518 IInternetProtocol *protocol;
2519 BYTE buf[512];
2520 ULONG cb;
2521 HRESULT hres;
2523 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2524 &IID_IUnknown, (void**)&unk);
2525 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2526 if(FAILED(hres))
2527 return;
2529 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2530 ok(hres == E_NOINTERFACE,
2531 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2533 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2534 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2535 IUnknown_Release(unk);
2536 if(FAILED(hres))
2537 return;
2539 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2540 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2542 if(SUCCEEDED(hres)) {
2543 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2544 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2545 ok(hres == S_OK, "Read failed: %08x\n", hres);
2546 ok(cb == 2, "cb=%u expected 2\n", cb);
2547 buf[2] = 0;
2548 ok(!memcmp(buf, file_with_hash ? "XX" : "<H", 2), "Unexpected data %s\n", buf);
2549 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2550 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2551 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2552 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2553 ok(cb == 0, "cb=%u expected 0\n", cb);
2554 hres = IInternetProtocol_UnlockRequest(protocol);
2555 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2558 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2559 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2560 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2561 hres = IInternetProtocol_LockRequest(protocol, 0);
2562 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2563 hres = IInternetProtocol_UnlockRequest(protocol);
2564 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2567 IInternetProtocol_Release(protocol);
2570 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2571 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2572 if(SUCCEEDED(hres)) {
2573 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2574 hres = IInternetProtocol_LockRequest(protocol, 0);
2575 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2576 hres = IInternetProtocol_Terminate(protocol, 0);
2577 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2578 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2579 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2580 hres = IInternetProtocol_UnlockRequest(protocol);
2581 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2582 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2583 todo_wine_if(file_with_hash) /* FIXME: An effect of UnlockRequest call? */
2584 ok(hres == S_OK, "Read failed: %08x\n", hres);
2585 hres = IInternetProtocol_Terminate(protocol, 0);
2586 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2589 IInternetProtocol_Release(protocol);
2592 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2593 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2594 if(SUCCEEDED(hres)) {
2595 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2596 hres = IInternetProtocol_Terminate(protocol, 0);
2597 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2598 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2599 ok(hres == S_OK, "Read failed: %08x\n", hres);
2600 ok(cb == 2, "cb=%u expected 2\n", cb);
2603 IInternetProtocol_Release(protocol);
2606 if(pCreateUri) {
2607 IInternetProtocolEx *protocolex;
2608 IUri *uri;
2610 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2611 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2613 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2614 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2616 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2617 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2618 ok(hres == S_OK, "Read failed: %08x\n", hres);
2619 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2620 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2621 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2622 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2625 IUri_Release(uri);
2626 IInternetProtocolEx_Release(protocolex);
2628 hres = pCreateUri(url, 0, 0, &uri);
2629 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2631 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2632 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2634 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2635 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2636 ok(hres == S_OK, "Read failed: %08x\n", hres);
2637 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2638 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2639 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2640 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2643 IUri_Release(uri);
2644 IInternetProtocolEx_Release(protocolex);
2645 }else {
2646 win_skip("Skipping file protocol StartEx tests\n");
2649 IClassFactory_Release(factory);
2652 static void test_file_protocol_fail(void)
2654 IInternetProtocol *protocol;
2655 HRESULT hres;
2657 static const WCHAR index_url2[] =
2658 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2660 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2661 &IID_IInternetProtocol, (void**)&protocol);
2662 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2663 if(FAILED(hres))
2664 return;
2666 SET_EXPECT(GetBindInfo);
2667 expect_hrResult = MK_E_SYNTAX;
2668 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2669 ok(hres == MK_E_SYNTAX ||
2670 hres == E_INVALIDARG,
2671 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2672 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2674 SET_EXPECT(GetBindInfo);
2675 if(!(bindf & BINDF_FROMURLMON))
2676 SET_EXPECT(ReportProgress_DIRECTBIND);
2677 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2678 SET_EXPECT(ReportResult);
2679 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2680 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2681 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2682 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2683 CHECK_CALLED(GetBindInfo);
2684 if(!(bindf & BINDF_FROMURLMON))
2685 CHECK_CALLED(ReportProgress_DIRECTBIND);
2686 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2687 CHECK_CALLED(ReportResult);
2689 IInternetProtocol_Release(protocol);
2691 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2692 &IID_IInternetProtocol, (void**)&protocol);
2693 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2694 if(FAILED(hres))
2695 return;
2697 SET_EXPECT(GetBindInfo);
2698 if(!(bindf & BINDF_FROMURLMON))
2699 SET_EXPECT(ReportProgress_DIRECTBIND);
2700 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2701 SET_EXPECT(ReportResult);
2702 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2704 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2705 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2706 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2707 CHECK_CALLED(GetBindInfo);
2708 if(!(bindf & BINDF_FROMURLMON))
2709 CHECK_CALLED(ReportProgress_DIRECTBIND);
2710 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2711 CHECK_CALLED(ReportResult);
2713 SET_EXPECT(GetBindInfo);
2714 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2715 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2716 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2718 SET_EXPECT(GetBindInfo);
2719 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2720 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2721 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2723 IInternetProtocol_Release(protocol);
2726 static void test_file_protocol(void) {
2727 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2728 DWORD size;
2729 ULONG len;
2730 HANDLE file;
2732 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2733 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2734 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2735 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2736 static const char html_doc[] = "<HTML></HTML>";
2737 static const WCHAR fragmentW[] = {'#','f','r','a','g',0};
2739 trace("Testing file protocol...\n");
2740 init_test(FILE_TEST, 0);
2742 SetLastError(0xdeadbeef);
2743 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2744 FILE_ATTRIBUTE_NORMAL, NULL);
2745 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2746 if(file == INVALID_HANDLE_VALUE)
2747 return;
2748 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2749 CloseHandle(file);
2751 file_name = wszIndexHtml;
2752 bindf = 0;
2753 test_file_protocol_url(index_url);
2754 bindf = BINDF_FROMURLMON;
2755 test_file_protocol_url(index_url);
2756 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2757 test_file_protocol_url(index_url);
2759 memcpy(buf, wszFile, sizeof(wszFile));
2760 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2761 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2762 buf[len++] = '\\';
2763 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2765 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2766 bindf = 0;
2767 test_file_protocol_url(buf);
2768 bindf = BINDF_FROMURLMON;
2769 test_file_protocol_url(buf);
2771 memcpy(buf, wszFile2, sizeof(wszFile2));
2772 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2773 file_name_buf[len++] = '\\';
2774 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2775 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2776 file_name = file_name_buf;
2777 bindf = 0;
2778 test_file_protocol_url(buf);
2779 bindf = BINDF_FROMURLMON;
2780 test_file_protocol_url(buf);
2782 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2783 test_file_protocol_url(buf);
2785 memcpy(buf, wszFile3, sizeof(wszFile3));
2786 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2787 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2788 buf[len++] = '\\';
2789 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2791 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2792 bindf = 0;
2793 test_file_protocol_url(buf);
2794 bindf = BINDF_FROMURLMON;
2795 test_file_protocol_url(buf);
2797 memcpy(buf, wszFile4, sizeof(wszFile4));
2798 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2799 file_name_buf[len++] = '\\';
2800 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2801 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2802 file_name = file_name_buf;
2803 bindf = 0;
2804 test_file_protocol_url(buf);
2805 bindf = BINDF_FROMURLMON;
2806 test_file_protocol_url(buf);
2808 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2809 test_file_protocol_url(buf);
2811 /* Fragment part of URL is skipped if the file doesn't exist. */
2812 lstrcatW(buf, fragmentW);
2813 test_file_protocol_url(buf);
2815 /* Fragment part is considered a part of the file name, if the file exsists. */
2816 len = lstrlenW(file_name_buf);
2817 lstrcpyW(file_name_buf+len, fragmentW);
2818 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2819 FILE_ATTRIBUTE_NORMAL, NULL);
2820 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2821 WriteFile(file, "XXX", 3, &size, NULL);
2822 CloseHandle(file);
2823 file_name_buf[len] = 0;
2825 file_with_hash = TRUE;
2826 test_file_protocol_url(buf);
2828 DeleteFileW(wszIndexHtml);
2829 DeleteFileW(file_name_buf);
2831 bindf = 0;
2832 test_file_protocol_fail();
2833 bindf = BINDF_FROMURLMON;
2834 test_file_protocol_fail();
2837 static void create_cache_entry(const WCHAR *urlw)
2839 FILETIME now, tomorrow, yesterday;
2840 char file_path[MAX_PATH];
2841 BYTE content[1000];
2842 ULARGE_INTEGER li;
2843 const char *url;
2844 HANDLE file;
2845 DWORD size;
2846 unsigned i;
2847 BOOL res;
2849 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2851 trace("Testing cache read...\n");
2853 url = w2a(urlw);
2855 for(i = 0; i < sizeof(content); i++)
2856 content[i] = '0' + (i%10);
2858 GetSystemTimeAsFileTime(&now);
2859 li.u.HighPart = now.dwHighDateTime;
2860 li.u.LowPart = now.dwLowDateTime;
2861 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2862 tomorrow.dwHighDateTime = li.u.HighPart;
2863 tomorrow.dwLowDateTime = li.u.LowPart;
2864 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2865 yesterday.dwHighDateTime = li.u.HighPart;
2866 yesterday.dwLowDateTime = li.u.LowPart;
2868 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2869 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2871 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2872 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2874 WriteFile(file, content, sizeof(content), &size, NULL);
2875 CloseHandle(file);
2877 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2878 cache_headers, sizeof(cache_headers)-1, "", 0);
2879 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2882 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2884 static BOOL got_user_agent = FALSE;
2885 IUri *uri = NULL;
2886 HRESULT hres;
2888 if(use_iuri && pCreateUri) {
2889 hres = pCreateUri(url, 0, 0, &uri);
2890 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2893 SET_EXPECT(GetBindInfo);
2894 if (!(bindf & BINDF_FROMURLMON))
2895 SET_EXPECT(ReportProgress_DIRECTBIND);
2896 if(!got_user_agent)
2897 SET_EXPECT(GetBindString_USER_AGENT);
2898 SET_EXPECT(GetBindString_ROOTDOC_URL);
2899 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2900 SET_EXPECT(QueryService_HttpNegotiate);
2901 SET_EXPECT(BeginningTransaction);
2902 SET_EXPECT(GetRootSecurityId);
2903 if(http_post_test) {
2904 SET_EXPECT(GetBindString_POST_COOKIE);
2905 if(http_post_test == TYMED_ISTREAM)
2906 SET_EXPECT(Stream_Seek);
2908 if(bind_from_cache) {
2909 SET_EXPECT(OnResponse);
2910 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2911 SET_EXPECT(ReportData);
2914 if(uri) {
2915 IInternetProtocolEx *protocolex;
2917 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2918 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2920 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2921 ok(hres == S_OK, "Start failed: %08x\n", hres);
2923 IInternetProtocolEx_Release(protocolex);
2924 IUri_Release(uri);
2925 }else {
2926 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2927 ok(hres == S_OK, "Start failed: %08x\n", hres);
2929 if(FAILED(hres))
2930 return FALSE;
2932 CHECK_CALLED(GetBindInfo);
2933 if (!(bindf & BINDF_FROMURLMON))
2934 CHECK_CALLED(ReportProgress_DIRECTBIND);
2935 if (!got_user_agent)
2937 CHECK_CALLED(GetBindString_USER_AGENT);
2938 got_user_agent = TRUE;
2940 CLEAR_CALLED(GetBindString_ROOTDOC_URL); /* New in IE11 */
2941 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2942 CHECK_CALLED(QueryService_HttpNegotiate);
2943 CHECK_CALLED(BeginningTransaction);
2944 /* GetRootSecurityId called on WinXP but not on Win98 */
2945 CLEAR_CALLED(GetRootSecurityId);
2946 if(http_post_test) {
2947 CHECK_CALLED(GetBindString_POST_COOKIE);
2948 if(http_post_test == TYMED_ISTREAM)
2949 CHECK_CALLED(Stream_Seek);
2951 if(bind_from_cache) {
2952 CHECK_CALLED(OnResponse);
2953 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2954 CHECK_CALLED(ReportData);
2957 return TRUE;
2960 static void test_protocol_terminate(IInternetProtocol *protocol)
2962 BYTE buf[3600];
2963 DWORD cb;
2964 HRESULT hres;
2966 hres = IInternetProtocol_LockRequest(protocol, 0);
2967 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2969 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2970 ok(hres == (test_abort ? S_OK : S_FALSE), "Read failed: %08x\n", hres);
2972 hres = IInternetProtocol_Terminate(protocol, 0);
2973 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2975 /* This wait is to give the internet handles being freed in Terminate
2976 * enough time to actually terminate in all cases. Internet handles
2977 * terminate asynchronously and native reuses the main InternetOpen
2978 * handle. The only case in which this seems to be necessary is on
2979 * wine with native wininet and urlmon, resulting in the next time
2980 * test_http_protocol_url being called the first data notification actually
2981 * being an extra last data notification from the previous connection
2982 * about once out of every ten times. */
2983 Sleep(100);
2985 hres = IInternetProtocol_UnlockRequest(protocol);
2986 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2989 static void test_http_info(IInternetProtocol *protocol)
2991 IWinInetHttpInfo *info;
2992 HRESULT hres;
2994 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2995 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2997 /* TODO */
2999 IWinInetHttpInfo_Release(info);
3002 /* is_first refers to whether this is the first call to this function
3003 * _for this url_ */
3004 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
3006 IInternetProtocolInfo *protocol_info;
3007 IClassFactory *factory;
3008 IUnknown *unk;
3009 HRESULT hres;
3011 init_test(prot, flags);
3012 http_url = url;
3013 http_post_test = tymed;
3015 if(flags & TEST_FROMCACHE)
3016 create_cache_entry(url);
3018 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
3019 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3020 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3021 if(FAILED(hres))
3022 return;
3024 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3025 ok(hres == E_NOINTERFACE,
3026 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3027 hres);
3029 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3030 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3031 IUnknown_Release(unk);
3032 if(FAILED(hres))
3033 return;
3035 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3036 (void**)&async_protocol);
3037 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3038 if(SUCCEEDED(hres)) {
3039 BYTE buf[3600];
3040 DWORD cb;
3041 ULONG ref;
3043 test_priority(async_protocol);
3044 test_http_info(async_protocol);
3046 SET_EXPECT(ReportProgress_COOKIE_SENT);
3047 if(http_is_first) {
3048 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3049 SET_EXPECT(ReportProgress_CONNECTING);
3051 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3052 if(test_redirect)
3053 SET_EXPECT(ReportProgress_REDIRECTING);
3054 SET_EXPECT(ReportProgress_PROXYDETECTING);
3055 if(prot == HTTP_TEST)
3056 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3057 else
3058 SET_EXPECT(QueryService_HttpSecurity);
3059 if(!(bindf & BINDF_FROMURLMON)) {
3060 SET_EXPECT(OnResponse);
3061 SET_EXPECT(ReportProgress_RAWMIMETYPE);
3062 SET_EXPECT(ReportData);
3063 } else {
3064 SET_EXPECT(Switch);
3067 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3068 IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3069 IInternetProtocol_Release(async_protocol);
3070 return;
3073 if(!direct_read && !test_abort && !bind_from_cache)
3074 SET_EXPECT(ReportResult);
3075 expect_hrResult = test_abort ? E_ABORT : S_OK;
3077 if(direct_read) {
3078 SET_EXPECT(Switch);
3079 while(wait_for_switch) {
3080 ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3081 CHECK_CALLED(Switch); /* Set in ReportData */
3082 call_continue(&continue_protdata);
3083 SetEvent(event_continue_done);
3085 }else if(bind_from_cache) {
3086 BYTE buf[1500];
3088 hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3089 ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3091 SET_EXPECT(ReportResult);
3092 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3093 ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3094 CHECK_CALLED(ReportResult);
3096 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3097 ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3098 }else {
3099 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3100 ok((hres == E_PENDING && cb==0) ||
3101 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3103 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3104 if(bindf & BINDF_FROMURLMON)
3105 CHECK_CALLED(Switch);
3106 else
3107 CHECK_CALLED(ReportData);
3108 if(prot == HTTPS_TEST)
3109 CLEAR_CALLED(QueryService_HttpSecurity);
3111 while(1) {
3112 if(bindf & BINDF_FROMURLMON)
3113 SET_EXPECT(Switch);
3114 else
3115 SET_EXPECT(ReportData);
3116 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3117 if(hres == E_PENDING) {
3118 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3119 ok((hres == E_PENDING && cb==0) ||
3120 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3121 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3122 if(bindf & BINDF_FROMURLMON)
3123 CHECK_CALLED(Switch);
3124 else
3125 CHECK_CALLED(ReportData);
3127 if(test_abort) {
3128 HRESULT hres;
3130 SET_EXPECT(ReportResult);
3131 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3132 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3133 CHECK_CALLED(ReportResult);
3135 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3136 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3137 break;
3139 }else {
3140 if(bindf & BINDF_FROMURLMON)
3141 CHECK_NOT_CALLED(Switch);
3142 else
3143 CHECK_NOT_CALLED(ReportData);
3144 if(cb == 0) break;
3147 if(!test_abort) {
3148 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3149 CHECK_CALLED(ReportResult);
3152 if(prot == HTTPS_TEST)
3153 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3155 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3156 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3158 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3159 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3161 test_protocol_terminate(async_protocol);
3163 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3164 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3166 ref = IInternetProtocol_Release(async_protocol);
3167 ok(!ref, "ref=%x\n", ref);
3170 IClassFactory_Release(factory);
3172 if(flags & TEST_FROMCACHE) {
3173 BOOL res;
3175 res = DeleteUrlCacheEntryW(url);
3176 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3180 static void test_http_protocol(void)
3182 static const WCHAR posttest_url[] =
3183 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3184 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3185 static const WCHAR redirect_url[] =
3186 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3187 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3188 static const WCHAR winetest_url[] =
3189 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3190 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3191 static const WCHAR empty_url[] =
3192 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3193 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3194 static const WCHAR cache_only_url[] =
3195 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3196 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3199 trace("Testing http protocol (not from urlmon)...\n");
3200 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3201 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3203 trace("Testing http protocol (from urlmon)...\n");
3204 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3205 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3207 trace("Testing http protocol (to file)...\n");
3208 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3209 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3211 trace("Testing http protocol (post data)...\n");
3212 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3213 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3215 trace("Testing http protocol (post data stream)...\n");
3216 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3218 trace("Testing http protocol (direct read)...\n");
3219 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3220 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3222 trace("Testing http protocol (redirected)...\n");
3223 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3224 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3226 trace("Testing http protocol empty file...\n");
3227 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3228 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3230 /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3231 * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3232 * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3233 * tests work on Windows and have them around for the future.
3235 if(broken(1)) {
3236 trace("Testing http protocol (from cache)...\n");
3237 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3238 test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3241 trace("Testing http protocol abort...\n");
3242 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3243 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3245 test_early_abort(&CLSID_HttpProtocol);
3246 test_early_abort(&CLSID_HttpSProtocol);
3249 static void test_https_protocol(void)
3251 static const WCHAR https_winehq_url[] =
3252 {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3253 't','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
3255 trace("Testing https protocol (from urlmon)...\n");
3256 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3257 test_http_protocol_url(https_winehq_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3261 static void test_ftp_protocol(void)
3263 IInternetProtocolInfo *protocol_info;
3264 IClassFactory *factory;
3265 IUnknown *unk;
3266 BYTE buf[4096];
3267 ULONG ref;
3268 DWORD cb;
3269 HRESULT hres;
3271 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3272 '/','p','u','b','/','o','t','h','e','r','/',
3273 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3275 trace("Testing ftp protocol...\n");
3277 init_test(FTP_TEST, 0);
3279 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3280 state = STATE_STARTDOWNLOADING;
3281 expect_hrResult = E_PENDING;
3283 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3284 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3285 if(FAILED(hres))
3286 return;
3288 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3289 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3291 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3292 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3293 IUnknown_Release(unk);
3294 if(FAILED(hres))
3295 return;
3297 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3298 (void**)&async_protocol);
3299 IClassFactory_Release(factory);
3300 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3302 test_priority(async_protocol);
3303 test_http_info(async_protocol);
3305 SET_EXPECT(GetBindInfo);
3306 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3307 SET_EXPECT(ReportProgress_CONNECTING);
3308 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3309 SET_EXPECT(Switch);
3311 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
3312 ok(hres == S_OK, "Start failed: %08x\n", hres);
3313 CHECK_CALLED(GetBindInfo);
3315 SET_EXPECT(ReportResult);
3317 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3318 ok((hres == E_PENDING && cb==0) ||
3319 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3321 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3323 while(1) {
3324 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3325 if(hres == E_PENDING)
3327 DWORD ret = WaitForSingleObject(event_complete, 90000);
3328 ok( ret == WAIT_OBJECT_0, "wait timed out\n" );
3329 if (ret != WAIT_OBJECT_0) break;
3331 else
3332 if(cb == 0) break;
3335 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3336 CHECK_CALLED(ReportResult);
3337 CHECK_CALLED(Switch);
3339 test_protocol_terminate(async_protocol);
3341 if(pCreateUri) {
3342 IInternetProtocolEx *protocolex;
3344 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3345 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3346 IInternetProtocolEx_Release(protocolex);
3349 ref = IInternetProtocol_Release(async_protocol);
3350 ok(!ref, "ref=%d\n", ref);
3352 test_early_abort(&CLSID_FtpProtocol);
3355 static void test_gopher_protocol(void)
3357 IInternetProtocolInfo *protocol_info;
3358 IClassFactory *factory;
3359 IUnknown *unk;
3360 HRESULT hres;
3362 trace("Testing gopher protocol...\n");
3364 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3365 ok(hres == S_OK ||
3366 broken(hres == REGDB_E_CLASSNOTREG || hres == CLASS_E_CLASSNOTAVAILABLE), /* Gopher protocol has been removed as of Vista */
3367 "CoGetClassObject failed: %08x\n", hres);
3368 if(FAILED(hres))
3369 return;
3371 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3372 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3374 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3375 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3376 IUnknown_Release(unk);
3377 if(FAILED(hres))
3378 return;
3380 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3381 (void**)&async_protocol);
3382 IClassFactory_Release(factory);
3383 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3385 test_priority(async_protocol);
3387 IInternetProtocol_Release(async_protocol);
3389 test_early_abort(&CLSID_GopherProtocol);
3392 static void test_mk_protocol(void)
3394 IInternetProtocolInfo *protocol_info;
3395 IInternetProtocol *protocol;
3396 IClassFactory *factory;
3397 IUnknown *unk;
3398 HRESULT hres;
3400 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
3401 ':',':','/','t','e','s','t','.','h','t','m','l',0};
3402 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
3404 trace("Testing mk protocol...\n");
3405 init_test(MK_TEST, 0);
3407 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
3408 &IID_IUnknown, (void**)&unk);
3409 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3411 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3412 ok(hres == E_NOINTERFACE,
3413 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3414 hres);
3416 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3417 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3418 IUnknown_Release(unk);
3419 if(FAILED(hres))
3420 return;
3422 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3423 (void**)&protocol);
3424 IClassFactory_Release(factory);
3425 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3427 SET_EXPECT(GetBindInfo);
3428 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
3429 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
3430 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
3431 CLEAR_CALLED(GetBindInfo);
3433 SET_EXPECT(GetBindInfo);
3434 SET_EXPECT(ReportProgress_DIRECTBIND);
3435 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3436 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3437 SET_EXPECT(ReportResult);
3438 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3440 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
3441 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
3442 hres == INET_E_INVALID_URL, /* win2k3 */
3443 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
3445 if (hres == INET_E_RESOURCE_NOT_FOUND) {
3446 CHECK_CALLED(GetBindInfo);
3447 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3448 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3449 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3450 CHECK_CALLED(ReportResult);
3451 }else {
3452 CLEAR_CALLED(GetBindInfo);
3453 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3454 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3455 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3456 CLEAR_CALLED(ReportResult);
3459 IInternetProtocol_Release(protocol);
3462 static void test_CreateBinding(void)
3464 IInternetProtocol *protocol;
3465 IInternetPriority *priority;
3466 IInternetSession *session;
3467 IWinInetHttpInfo *http_info;
3468 IWinInetInfo *inet_info;
3469 LONG p;
3470 BYTE buf[1000];
3471 DWORD read;
3472 HRESULT hres;
3474 static const WCHAR test_url[] =
3475 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
3476 static const WCHAR wsz_test[] = {'t','e','s','t',0};
3478 trace("Testing CreateBinding...\n");
3479 init_test(BIND_TEST, TEST_BINDING);
3481 hres = pCoInternetGetSession(0, &session, 0);
3482 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3484 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
3485 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3487 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3488 binding_protocol = protocol;
3489 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3490 ok(protocol != NULL, "protocol == NULL\n");
3492 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3493 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3495 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3496 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
3498 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
3499 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3500 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
3501 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3502 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3503 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3505 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
3506 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
3508 p = 0xdeadbeef;
3509 hres = IInternetPriority_GetPriority(priority, &p);
3510 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3511 ok(!p, "p=%d\n", p);
3513 ex_priority = 100;
3514 hres = IInternetPriority_SetPriority(priority, 100);
3515 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3517 p = 0xdeadbeef;
3518 hres = IInternetPriority_GetPriority(priority, &p);
3519 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3520 ok(p == 100, "p=%d\n", p);
3522 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3523 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3525 SET_EXPECT(QueryService_InternetProtocol);
3526 SET_EXPECT(CreateInstance);
3527 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3528 SET_EXPECT(SetPriority);
3529 SET_EXPECT(Start);
3531 expect_hrResult = S_OK;
3532 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3533 ok(hres == S_OK, "Start failed: %08x\n", hres);
3535 CHECK_CALLED(QueryService_InternetProtocol);
3536 CHECK_CALLED(CreateInstance);
3537 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3538 CHECK_CALLED(SetPriority);
3539 CHECK_CALLED(Start);
3541 SET_EXPECT(QueryInterface_IWinInetInfo);
3542 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3543 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3544 CHECK_CALLED(QueryInterface_IWinInetInfo);
3546 SET_EXPECT(QueryInterface_IWinInetInfo);
3547 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3548 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3549 CHECK_CALLED(QueryInterface_IWinInetInfo);
3551 SET_EXPECT(QueryInterface_IWinInetHttpInfo);
3552 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
3553 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3554 CHECK_CALLED(QueryInterface_IWinInetHttpInfo);
3556 SET_EXPECT(Read);
3557 read = 0xdeadbeef;
3558 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3559 ok(hres == S_OK, "Read failed: %08x\n", hres);
3560 ok(read == 100, "read = %d\n", read);
3561 CHECK_CALLED(Read);
3563 SET_EXPECT(Read);
3564 read = 0xdeadbeef;
3565 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3566 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3567 ok(!read, "read = %d\n", read);
3568 CHECK_CALLED(Read);
3570 p = 0xdeadbeef;
3571 hres = IInternetPriority_GetPriority(priority, &p);
3572 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3573 ok(p == 100, "p=%d\n", p);
3575 hres = IInternetPriority_SetPriority(priority, 101);
3576 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3578 SET_EXPECT(Terminate);
3579 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
3580 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3581 CHECK_CALLED(Terminate);
3583 SET_EXPECT(Continue);
3584 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
3585 ok(hres == S_OK, "Switch failed: %08x\n", hres);
3586 CHECK_CALLED(Continue);
3588 hres = IInternetProtocolSink_ReportProgress(binding_sink,
3589 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
3590 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
3592 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
3593 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
3595 hres = IInternetProtocolSink_ReportData(binding_sink, 0, 0, 0);
3596 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
3598 IInternetProtocolSink_Release(binding_sink);
3599 IInternetPriority_Release(priority);
3600 IInternetBindInfo_Release(prot_bind_info);
3601 IInternetProtocol_Release(protocol);
3603 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3604 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3605 ok(protocol != NULL, "protocol == NULL\n");
3607 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3608 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3610 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
3611 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3613 IInternetProtocol_Release(protocol);
3615 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, wsz_test);
3616 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3618 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3619 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3620 ok(protocol != NULL, "protocol == NULL\n");
3622 SET_EXPECT(QueryService_InternetProtocol);
3623 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3624 ok(hres == MK_E_SYNTAX, "Start failed: %08x, expected MK_E_SYNTAX\n", hres);
3625 CHECK_CALLED(QueryService_InternetProtocol);
3627 IInternetProtocol_Release(protocol);
3629 IInternetSession_Release(session);
3632 static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
3634 IInternetProtocolEx *protocolex = NULL;
3635 IInternetProtocol *protocol;
3636 IInternetSession *session;
3637 IUri *uri = NULL;
3638 ULONG ref;
3639 HRESULT hres;
3641 pi = grf_pi;
3643 init_test(prot, test_flags|TEST_BINDING);
3645 hres = pCoInternetGetSession(0, &session, 0);
3646 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3648 if(test_flags & TEST_EMULATEPROT) {
3649 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
3650 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3653 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
3654 binding_protocol = protocol;
3655 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3656 ok(protocol != NULL, "protocol == NULL\n");
3658 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3659 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3661 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3662 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
3664 if(test_flags & TEST_USEIURI) {
3665 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3666 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3668 hres = pCreateUri(binding_urls[prot], Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
3669 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3672 ex_priority = 0;
3673 SET_EXPECT(QueryService_InternetProtocol);
3674 SET_EXPECT(CreateInstance);
3675 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3676 SET_EXPECT(SetPriority);
3677 if(impl_protex)
3678 SET_EXPECT(StartEx);
3679 else
3680 SET_EXPECT(Start);
3682 expect_hrResult = S_OK;
3684 if(protocolex) {
3685 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, pi, 0);
3686 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
3687 }else {
3688 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0);
3689 ok(hres == S_OK, "Start failed: %08x\n", hres);
3692 CHECK_CALLED(QueryService_InternetProtocol);
3693 CHECK_CALLED(CreateInstance);
3694 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3695 CLEAR_CALLED(SetPriority); /* IE11 does not call it. */
3696 if(impl_protex)
3697 CHECK_CALLED(StartEx);
3698 else
3699 CHECK_CALLED(Start);
3701 if(protocolex)
3702 IInternetProtocolEx_Release(protocolex);
3703 if(uri)
3704 IUri_Release(uri);
3706 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
3707 while(prot_state < 4) {
3708 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3709 if(mimefilter_test && filtered_protocol) {
3710 SET_EXPECT(Continue);
3711 IInternetProtocol_Continue(filtered_protocol, pdata);
3712 CHECK_CALLED(Continue);
3713 }else {
3714 SET_EXPECT(Continue);
3715 IInternetProtocol_Continue(protocol, pdata);
3716 CHECK_CALLED(Continue);
3718 if(test_abort && prot_state == 2) {
3719 SET_EXPECT(Abort);
3720 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3721 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3722 CHECK_CALLED(Abort);
3724 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3725 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3726 SetEvent(event_complete2);
3727 break;
3729 SetEvent(event_complete2);
3731 if(direct_read)
3732 CHECK_CALLED(ReportData); /* Set in ReportResult */
3733 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3734 }else {
3735 if(mimefilter_test)
3736 SET_EXPECT(MimeFilter_LockRequest);
3737 else
3738 SET_EXPECT(LockRequest);
3739 hres = IInternetProtocol_LockRequest(protocol, 0);
3740 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3741 if(mimefilter_test)
3742 CHECK_CALLED(MimeFilter_LockRequest);
3743 else
3744 CHECK_CALLED(LockRequest);
3746 if(mimefilter_test)
3747 SET_EXPECT(MimeFilter_UnlockRequest);
3748 else
3749 SET_EXPECT(UnlockRequest);
3750 hres = IInternetProtocol_UnlockRequest(protocol);
3751 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3752 if(mimefilter_test)
3753 CHECK_CALLED(MimeFilter_UnlockRequest);
3754 else
3755 CHECK_CALLED(UnlockRequest);
3758 if(mimefilter_test)
3759 SET_EXPECT(MimeFilter_Terminate);
3760 else
3761 SET_EXPECT(Terminate);
3762 hres = IInternetProtocol_Terminate(protocol, 0);
3763 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3764 if(mimefilter_test)
3765 CLEAR_CALLED(MimeFilter_Terminate);
3766 else
3767 CHECK_CALLED(Terminate);
3769 if(filtered_protocol)
3770 IInternetProtocol_Release(filtered_protocol);
3771 IInternetBindInfo_Release(prot_bind_info);
3772 IInternetProtocolSink_Release(binding_sink);
3773 ref = IInternetProtocol_Release(protocol);
3774 ok(!ref, "ref=%u, expected 0\n", ref);
3776 if(test_flags & TEST_EMULATEPROT) {
3777 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]);
3778 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3781 IInternetSession_Release(session);
3784 START_TEST(protocol)
3786 HMODULE hurlmon;
3788 hurlmon = GetModuleHandleA("urlmon.dll");
3789 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
3790 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
3791 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3793 if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3794 win_skip("Various needed functions not present, too old IE\n");
3795 return;
3798 if(!pCreateUri)
3799 win_skip("CreateUri not supported\n");
3801 OleInitialize(NULL);
3803 event_complete = CreateEventW(NULL, FALSE, FALSE, NULL);
3804 event_complete2 = CreateEventW(NULL, FALSE, FALSE, NULL);
3805 event_continue = CreateEventW(NULL, FALSE, FALSE, NULL);
3806 event_continue_done = CreateEventW(NULL, FALSE, FALSE, NULL);
3807 thread_id = GetCurrentThreadId();
3809 test_file_protocol();
3810 test_http_protocol();
3811 if(pCreateUri)
3812 test_https_protocol();
3813 else
3814 win_skip("Skipping https tests on too old platform\n");
3815 test_ftp_protocol();
3816 test_gopher_protocol();
3817 test_mk_protocol();
3818 test_CreateBinding();
3820 bindf &= ~BINDF_FROMURLMON;
3821 trace("Testing file binding (mime verification, emulate prot)...\n");
3822 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3823 trace("Testing http binding (mime verification, emulate prot)...\n");
3824 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3825 trace("Testing its binding (mime verification, emulate prot)...\n");
3826 test_binding(ITS_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3827 trace("Testing http binding (mime verification, emulate prot, short read, direct read)...\n");
3828 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_SHORT_READ|TEST_DIRECT_READ);
3829 trace("Testing file binding (mime verification, emulate prot, mime filter)...\n");
3830 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3831 trace("Testing http binding (mime verification, emulate prot, mime filter)...\n");
3832 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3833 trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n");
3834 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME);
3835 trace("Testing http binding (mime verification, emulate prot, direct read)...\n");
3836 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
3837 trace("Testing http binding (mime verification, emulate prot, abort)...\n");
3838 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
3839 if(pCreateUri) {
3840 trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
3841 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);
3842 trace("Testing file binding (use IUri, impl StartEx, mime verification, emulate prot)...\n");
3843 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI|TEST_IMPLPROTEX);
3844 trace("Testing file binding (impl StartEx, mime verification, emulate prot)...\n");
3845 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_IMPLPROTEX);
3848 CloseHandle(event_complete);
3849 CloseHandle(event_complete2);
3850 CloseHandle(event_continue);
3851 CloseHandle(event_continue_done);
3853 OleUninitialize();