urlmon/tests: Clarify ok() condition (PVS-Studio).
[wine.git] / dlls / urlmon / tests / protocol.c
blob9aadf1e5a7ba5174694039d06ff9a64777ba4788
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;
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 trace("continue in state %d\n", state);
585 if(state == STATE_CONNECTING) {
586 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
587 if (http_is_first){
588 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
589 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
591 CLEAR_CALLED(ReportProgress_CONNECTING);
593 if(tested_protocol == FTP_TEST)
594 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
595 else if (tested_protocol != HTTPS_TEST)
596 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
597 if(test_redirect)
598 CHECK_CALLED(ReportProgress_REDIRECTING);
599 state = test_async_req ? STATE_SENDINGREQUEST : STATE_STARTDOWNLOADING;
602 switch(state) {
603 case STATE_SENDINGREQUEST:
604 SET_EXPECT(Stream_Read);
605 SET_EXPECT(ReportProgress_SENDINGREQUEST);
606 break;
607 case STATE_STARTDOWNLOADING:
608 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
609 SET_EXPECT(OnResponse);
610 if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file)
611 SET_EXPECT(ReportProgress_ACCEPTRANGES);
612 SET_EXPECT(ReportProgress_ENCODING);
613 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
614 if(bindf & BINDF_NEEDFILE)
615 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
617 default:
618 break;
621 if(state != STATE_SENDINGREQUEST)
622 SET_EXPECT(ReportData);
623 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
624 ok(hres == S_OK, "Continue failed: %08x\n", hres);
625 if(tested_protocol == FTP_TEST || security_problem)
626 CLEAR_CALLED(ReportData);
627 else if(state != STATE_SENDINGREQUEST)
628 CHECK_CALLED(ReportData);
630 switch(state) {
631 case STATE_SENDINGREQUEST:
632 CHECK_CALLED(Stream_Read);
633 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
634 state = STATE_STARTDOWNLOADING;
635 break;
636 case STATE_STARTDOWNLOADING:
637 if (! security_problem)
639 state = STATE_DOWNLOADING;
640 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
641 CHECK_CALLED(OnResponse);
642 if(tested_protocol == HTTPS_TEST || empty_file)
643 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
644 else if(test_redirect || test_abort)
645 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
646 CLEAR_CALLED(ReportProgress_ENCODING);
647 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
648 if(bindf & BINDF_NEEDFILE)
649 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
652 else
654 security_problem = FALSE;
655 SET_EXPECT(ReportProgress_CONNECTING);
657 default:
658 break;
662 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
664 if(tested_protocol == FTP_TEST)
665 CHECK_EXPECT2(Switch);
666 else
667 CHECK_EXPECT(Switch);
669 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
670 if(binding_test) {
671 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
672 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
673 pProtocolData->grfFlags, protocoldata.grfFlags );
674 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
675 pProtocolData->dwState, protocoldata.dwState );
676 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
677 pProtocolData->pData, protocoldata.pData );
678 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
679 pProtocolData->cbData, protocoldata.cbData );
682 pdata = pProtocolData;
684 if(binding_test) {
685 SetEvent(event_complete);
686 ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
687 return S_OK;
688 }if(direct_read) {
689 continue_protdata = *pProtocolData;
690 SetEvent(event_continue);
691 ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
692 }else {
693 call_continue(pProtocolData);
694 SetEvent(event_complete);
697 return S_OK;
700 static const char *status_names[] =
702 "0",
703 "FINDINGRESOURCE",
704 "CONNECTING",
705 "REDIRECTING",
706 "BEGINDOWNLOADDATA",
707 "DOWNLOADINGDATA",
708 "ENDDOWNLOADDATA",
709 "BEGINDOWNLOADCOMPONENTS",
710 "INSTALLINGCOMPONENTS",
711 "ENDDOWNLOADCOMPONENTS",
712 "USINGCACHEDCOPY",
713 "SENDINGREQUEST",
714 "CLASSIDAVAILABLE",
715 "MIMETYPEAVAILABLE",
716 "CACHEFILENAMEAVAILABLE",
717 "BEGINSYNCOPERATION",
718 "ENDSYNCOPERATION",
719 "BEGINUPLOADDATA",
720 "UPLOADINGDATA",
721 "ENDUPLOADINGDATA",
722 "PROTOCOLCLASSID",
723 "ENCODING",
724 "VERIFIEDMIMETYPEAVAILABLE",
725 "CLASSINSTALLLOCATION",
726 "DECODING",
727 "LOADINGMIMEHANDLER",
728 "CONTENTDISPOSITIONATTACH",
729 "FILTERREPORTMIMETYPE",
730 "CLSIDCANINSTANTIATE",
731 "IUNKNOWNAVAILABLE",
732 "DIRECTBIND",
733 "RAWMIMETYPE",
734 "PROXYDETECTING",
735 "ACCEPTRANGES",
736 "COOKIE_SENT",
737 "COMPACT_POLICY_RECEIVED",
738 "COOKIE_SUPPRESSED",
739 "COOKIE_STATE_UNKNOWN",
740 "COOKIE_STATE_ACCEPT",
741 "COOKIE_STATE_REJECT",
742 "COOKIE_STATE_PROMPT",
743 "COOKIE_STATE_LEASH",
744 "COOKIE_STATE_DOWNGRADE",
745 "POLICY_HREF",
746 "P3P_HEADER",
747 "SESSION_COOKIE_RECEIVED",
748 "PERSISTENT_COOKIE_RECEIVED",
749 "SESSION_COOKIES_ALLOWED",
750 "CACHECONTROL",
751 "CONTENTDISPOSITIONFILENAME",
752 "MIMETEXTPLAINMISMATCH",
753 "PUBLISHERAVAILABLE",
754 "DISPLAYNAMEAVAILABLE"
757 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
758 LPCWSTR szStatusText)
760 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
761 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
762 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
764 if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0]))
765 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
766 else
767 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
769 switch(ulStatusCode) {
770 case BINDSTATUS_MIMETYPEAVAILABLE:
771 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
772 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
773 if(!short_read || !direct_read)
774 CHECK_CALLED(Read); /* set in Continue */
775 else if(short_read)
776 CHECK_CALLED(Read2); /* set in Read */
778 ok(szStatusText != NULL, "szStatusText == NULL\n");
779 if(szStatusText) {
780 if(tested_protocol == BIND_TEST)
781 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
782 else if (http_post_test)
783 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
784 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
785 "szStatusText != text/plain\n");
786 else if(empty_file)
787 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
788 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
789 && tested_protocol==HTTP_TEST && !short_read)
790 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
791 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
792 "szStatusText != image/gif\n");
793 else if(!mimefilter_test)
794 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
795 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
796 "szStatusText != text/html\n");
798 break;
799 case BINDSTATUS_DIRECTBIND:
800 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
801 ok(szStatusText == NULL, "szStatusText != NULL\n");
802 break;
803 case BINDSTATUS_RAWMIMETYPE:
804 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
805 ok(szStatusText != NULL, "szStatusText == NULL\n");
806 if(szStatusText)
807 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
808 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
809 "szStatusText != text/html\n");
810 break;
811 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
812 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
813 ok(szStatusText != NULL, "szStatusText == NULL\n");
814 if(szStatusText) {
815 if(binding_test)
816 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
817 else if(tested_protocol == FILE_TEST)
818 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
819 else
820 ok(szStatusText != NULL, "szStatusText == NULL\n");
822 break;
823 case BINDSTATUS_FINDINGRESOURCE:
824 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
825 ok(szStatusText != NULL, "szStatusText == NULL\n");
826 break;
827 case BINDSTATUS_CONNECTING:
828 CHECK_EXPECT2(ReportProgress_CONNECTING);
829 ok(szStatusText != NULL, "szStatusText == NULL\n");
830 break;
831 case BINDSTATUS_SENDINGREQUEST:
832 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
833 if(tested_protocol == FILE_TEST || tested_protocol == ITS_TEST) {
834 ok(szStatusText != NULL, "szStatusText == NULL\n");
835 if(szStatusText)
836 ok(!*szStatusText, "wrong szStatusText\n");
838 break;
839 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
840 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
841 ok(szStatusText != NULL, "szStatusText == NULL\n");
842 if(szStatusText)
843 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
844 break;
845 case BINDSTATUS_PROTOCOLCLASSID:
846 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
847 ok(szStatusText != NULL, "szStatusText == NULL\n");
848 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
849 break;
850 case BINDSTATUS_COOKIE_SENT:
851 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
852 ok(szStatusText == NULL, "szStatusText != NULL\n");
853 break;
854 case BINDSTATUS_REDIRECTING:
855 CHECK_EXPECT(ReportProgress_REDIRECTING);
856 if(test_redirect)
857 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
858 else
859 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
860 break;
861 case BINDSTATUS_ENCODING:
862 CHECK_EXPECT(ReportProgress_ENCODING);
863 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
864 break;
865 case BINDSTATUS_ACCEPTRANGES:
866 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
867 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
868 break;
869 case BINDSTATUS_PROXYDETECTING:
870 if(!called_ReportProgress_PROXYDETECTING)
871 SET_EXPECT(ReportProgress_CONNECTING);
872 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
873 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
874 break;
875 case BINDSTATUS_LOADINGMIMEHANDLER:
876 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
877 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
878 break;
879 case BINDSTATUS_DECODING:
880 CHECK_EXPECT(ReportProgress_DECODING);
881 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
882 break;
883 case BINDSTATUS_RESERVED_7:
884 trace("BINDSTATUS_RESERVED_7\n");
885 break;
886 default:
887 ok(0, "Unexpected status %d (%d)\n", ulStatusCode, ulStatusCode-BINDSTATUS_LAST);
890 return S_OK;
893 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
894 ULONG ulProgress, ULONG ulProgressMax)
896 HRESULT hres;
898 static int rec_depth;
899 rec_depth++;
901 if(!mimefilter_test && (tested_protocol == FILE_TEST || tested_protocol == ITS_TEST)) {
902 CHECK_EXPECT2(ReportData);
904 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
905 ulProgress, ulProgressMax);
906 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
907 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
908 if(tested_protocol == FILE_TEST)
909 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
910 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
911 "grcfBSCF = %08x\n", grfBSCF);
912 else
913 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
914 }else if(bind_from_cache) {
915 CHECK_EXPECT(ReportData);
917 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
918 ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
919 ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
920 }else if(direct_read) {
921 BYTE buf[14096];
922 ULONG read;
924 if(!read_report_data && rec_depth == 1) {
925 BOOL reported_all_data = called_ReportData2;
927 CHECK_EXPECT2(ReportData);
929 if(short_read) {
930 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
931 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
932 "grcfBSCF = %08x\n", grfBSCF);
933 CHECK_CALLED(Read); /* Set in Continue */
934 first_data_notif = FALSE;
935 }else if(first_data_notif) {
936 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
937 first_data_notif = FALSE;
938 }else if(reported_all_data) {
939 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
940 "grcfBSCF = %08x\n", grfBSCF);
941 }else if(!direct_read) {
942 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
945 do {
946 read = 0;
947 if(emulate_prot)
948 SET_EXPECT(Read);
949 else
950 SET_EXPECT(ReportData2);
951 SET_EXPECT(ReportResult);
952 if(!emulate_prot)
953 SET_EXPECT(Switch);
954 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
955 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
956 if(hres == S_OK)
957 ok(read, "read == 0\n");
958 if(reported_all_data)
959 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
960 if(!emulate_prot && hres != E_PENDING)
961 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
962 if(emulate_prot)
963 CHECK_CALLED(Read);
964 if(!reported_all_data && called_ReportData2) {
965 if(!emulate_prot)
966 CHECK_CALLED(ReportData2);
967 CHECK_CALLED(ReportResult);
968 reported_all_data = TRUE;
969 }else {
970 if(!emulate_prot)
971 CHECK_NOT_CALLED(ReportData2);
972 CHECK_NOT_CALLED(ReportResult);
974 }while(hres == S_OK);
975 if(hres == S_FALSE)
976 wait_for_switch = FALSE;
977 }else {
978 CHECK_EXPECT(ReportData2);
980 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
982 read = 0xdeadbeef;
983 if(emulate_prot)
984 SET_EXPECT(Read2);
985 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
986 if(emulate_prot)
987 CHECK_CALLED(Read2);
988 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
989 ok(!read, "read = %d\n", read);
991 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST
992 || tested_protocol == FTP_TEST)) {
993 if(empty_file)
994 CHECK_EXPECT2(ReportData);
995 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
996 CHECK_EXPECT(ReportData);
997 else if (http_post_test)
998 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
1000 if(empty_file) {
1001 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
1002 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
1003 }else {
1004 ok(ulProgress, "ulProgress == 0\n");
1007 if(empty_file) {
1008 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
1009 "grcfBSCF = %08x\n", grfBSCF);
1010 first_data_notif = FALSE;
1011 }else if(first_data_notif) {
1012 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1013 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1014 "grcfBSCF = %08x\n", grfBSCF);
1015 first_data_notif = FALSE;
1016 } else {
1017 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1018 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1019 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1020 "grcfBSCF = %08x\n", grfBSCF);
1023 if(!(bindf & BINDF_FROMURLMON) &&
1024 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1025 if(state == STATE_CONNECTING) {
1026 state = STATE_DOWNLOADING;
1027 if(http_is_first) {
1028 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1029 CHECK_CALLED(ReportProgress_CONNECTING);
1031 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1032 CHECK_CALLED(OnResponse);
1033 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1035 SetEvent(event_complete);
1037 }else if(!read_report_data) {
1038 BYTE buf[1000];
1039 ULONG read;
1040 HRESULT hres;
1042 CHECK_EXPECT(ReportData);
1044 if(tested_protocol != BIND_TEST) {
1045 do {
1046 if(mimefilter_test)
1047 SET_EXPECT(MimeFilter_Read);
1048 else if(rec_depth > 1)
1049 SET_EXPECT(Read2);
1050 else
1051 SET_EXPECT(Read);
1052 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1053 if(mimefilter_test)
1054 CHECK_CALLED(MimeFilter_Read);
1055 else if(rec_depth > 1)
1056 CHECK_CALLED(Read2);
1057 else
1058 CHECK_CALLED(Read);
1059 }while(hres == S_OK);
1063 rec_depth--;
1064 return S_OK;
1067 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1068 DWORD dwError, LPCWSTR szResult)
1070 CHECK_EXPECT(ReportResult);
1072 if(tested_protocol == FTP_TEST)
1073 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1074 else
1075 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1076 hrResult, expect_hrResult);
1077 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort)
1078 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1079 else
1080 ok(dwError != ERROR_SUCCESS ||
1081 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1082 "dwError == ERROR_SUCCESS\n");
1083 ok(!szResult, "szResult != NULL\n");
1085 if(direct_read)
1086 SET_EXPECT(ReportData); /* checked after main loop */
1088 return S_OK;
1091 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1092 ProtocolSink_QueryInterface,
1093 ProtocolSink_AddRef,
1094 ProtocolSink_Release,
1095 ProtocolSink_Switch,
1096 ProtocolSink_ReportProgress,
1097 ProtocolSink_ReportData,
1098 ProtocolSink_ReportResult
1101 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
1103 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
1105 ok(0, "unexpected call\n");
1106 return E_NOTIMPL;
1109 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1111 return 2;
1114 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1116 return 1;
1119 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1121 HRESULT hres;
1123 CHECK_EXPECT(MimeFilter_Switch);
1125 SET_EXPECT(Switch);
1126 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1127 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1128 CHECK_CALLED(Switch);
1130 return S_OK;
1133 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1134 LPCWSTR szStatusText)
1136 switch(ulStatusCode) {
1137 case BINDSTATUS_LOADINGMIMEHANDLER:
1139 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1140 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1141 * ProtocolSink_ReportProgress to workaround it.
1143 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1144 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1145 break;
1146 default:
1147 ok(0, "Unexpected status code %d\n", ulStatusCode);
1150 return S_OK;
1153 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1154 ULONG ulProgress, ULONG ulProgressMax)
1156 DWORD read = 0;
1157 BYTE buf[8192];
1158 HRESULT hres;
1159 BOOL report_mime = FALSE;
1161 CHECK_EXPECT(MimeFilter_ReportData);
1163 if(!filter_state && !no_mime) {
1164 SET_EXPECT(Read);
1165 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1166 if(tested_protocol == HTTP_TEST)
1167 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1168 else
1169 ok(hres == S_OK, "Read failed: %08x\n", hres);
1170 CHECK_CALLED(Read);
1172 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1173 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1174 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1175 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1177 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1178 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1179 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1180 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1182 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1185 if(no_mime && prot_read<200) {
1186 SET_EXPECT(Read);
1187 }else if(no_mime && prot_read<300) {
1188 report_mime = TRUE;
1189 SET_EXPECT(Read);
1190 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1191 SET_EXPECT(ReportData);
1192 }else if(!read_report_data) {
1193 SET_EXPECT(ReportData);
1195 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1196 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1197 if(no_mime && prot_read<=200) {
1198 CHECK_CALLED(Read);
1199 }else if(report_mime) {
1200 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1201 CHECK_CALLED(ReportData);
1202 }else if(!read_report_data) {
1203 CHECK_CALLED(ReportData);
1206 if(!filter_state)
1207 filter_state = 1;
1209 return S_OK;
1212 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1213 DWORD dwError, LPCWSTR szResult)
1215 HRESULT hres;
1217 CHECK_EXPECT(MimeFilter_ReportResult);
1219 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1220 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1221 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1223 SET_EXPECT(ReportResult);
1224 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1225 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1226 CHECK_CALLED(ReportResult);
1228 return S_OK;
1231 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1232 MimeProtocolSink_QueryInterface,
1233 MimeProtocolSink_AddRef,
1234 MimeProtocolSink_Release,
1235 MimeProtocolSink_Switch,
1236 MimeProtocolSink_ReportProgress,
1237 MimeProtocolSink_ReportData,
1238 MimeProtocolSink_ReportResult
1241 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1243 static HRESULT QueryInterface(REFIID riid, void **ppv)
1245 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1246 static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1248 *ppv = NULL;
1250 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1251 *ppv = &protocol_sink;
1252 if(IsEqualGUID(&IID_IServiceProvider, riid))
1253 *ppv = &service_provider;
1254 if(IsEqualGUID(&IID_IUriContainer, riid))
1255 return E_NOINTERFACE; /* TODO */
1257 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1258 if(IsEqualGUID(&IID_undocumented, riid))
1259 return E_NOINTERFACE;
1260 /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1261 if(IsEqualGUID(&IID_undocumentedIE10, riid))
1262 return E_NOINTERFACE;
1264 if(*ppv)
1265 return S_OK;
1267 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1268 return E_NOINTERFACE;
1271 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1273 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1274 *ppv = iface;
1275 return S_OK;
1277 return E_NOINTERFACE;
1280 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1282 return 2;
1285 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1287 return 1;
1290 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1292 DWORD cbSize;
1294 CHECK_EXPECT(GetBindInfo);
1296 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1297 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1298 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1300 *grfBINDF = bindf;
1301 if(binding_test)
1302 *grfBINDF |= BINDF_FROMURLMON;
1303 cbSize = pbindinfo->cbSize;
1304 memset(pbindinfo, 0, cbSize);
1305 pbindinfo->cbSize = cbSize;
1307 if(http_post_test)
1309 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1310 pbindinfo->dwBindVerb = BINDVERB_POST;
1311 pbindinfo->stgmedData.tymed = http_post_test;
1313 if(http_post_test == TYMED_HGLOBAL) {
1314 HGLOBAL data;
1316 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1317 data = GlobalAlloc(GPTR, sizeof(post_data));
1318 memcpy(data, post_data, sizeof(post_data));
1319 U(pbindinfo->stgmedData).hGlobal = data;
1320 }else {
1321 IStream *post_stream;
1322 HGLOBAL data;
1323 HRESULT hres;
1325 if(0) {
1326 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1327 data = GlobalAlloc(GPTR, sizeof(post_data));
1328 memcpy(data, post_data, sizeof(post_data));
1329 U(pbindinfo->stgmedData).hGlobal = data;
1331 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1332 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1334 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1336 U(pbindinfo->stgmedData).pstm = &Stream;
1340 return S_OK;
1343 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1344 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1346 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1347 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1349 switch(ulStringType) {
1350 case BINDSTRING_ACCEPT_MIMES:
1351 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1352 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1353 if(pcElFetched) {
1354 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1355 *pcElFetched = 1;
1357 if(ppwzStr) {
1358 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1359 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1361 return S_OK;
1362 case BINDSTRING_USER_AGENT:
1363 CHECK_EXPECT(GetBindString_USER_AGENT);
1364 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1365 if(pcElFetched) {
1366 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1367 *pcElFetched = 1;
1369 if(ppwzStr) {
1370 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1371 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1373 return S_OK;
1374 case BINDSTRING_POST_COOKIE:
1375 CHECK_EXPECT(GetBindString_POST_COOKIE);
1376 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1377 if(pcElFetched)
1378 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1379 return S_OK;
1380 case BINDSTRING_URL: {
1381 DWORD size;
1383 CHECK_EXPECT(GetBindString_URL);
1384 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1385 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1386 *pcElFetched = 1;
1388 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1389 *ppwzStr = CoTaskMemAlloc(size);
1390 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1391 return S_OK;
1393 case BINDSTRING_ROOTDOC_URL:
1394 CHECK_EXPECT(GetBindString_ROOTDOC_URL);
1395 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1396 return E_NOTIMPL;
1397 default:
1398 ok(0, "unexpected ulStringType %d\n", ulStringType);
1401 return E_NOTIMPL;
1404 static IInternetBindInfoVtbl bind_info_vtbl = {
1405 BindInfo_QueryInterface,
1406 BindInfo_AddRef,
1407 BindInfo_Release,
1408 BindInfo_GetBindInfo,
1409 BindInfo_GetBindString
1412 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1414 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1415 REFIID riid, void **ppv)
1417 ok(0, "unexpected call\n");
1418 return E_NOINTERFACE;
1421 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1423 return 2;
1426 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1428 return 1;
1431 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1433 CHECK_EXPECT(SetPriority);
1434 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1435 return S_OK;
1438 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1440 ok(0, "unexpected call\n");
1441 return E_NOTIMPL;
1445 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1446 InternetPriority_QueryInterface,
1447 InternetPriority_AddRef,
1448 InternetPriority_Release,
1449 InternetPriority_SetPriority,
1450 InternetPriority_GetPriority
1453 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1455 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1457 return 2;
1460 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1462 return 1;
1465 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1466 DWORD dwOptions)
1468 HRESULT hres;
1470 CHECK_EXPECT(Abort);
1472 SET_EXPECT(ReportResult);
1473 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1474 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1475 CHECK_CALLED(ReportResult);
1477 return S_OK;
1480 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1482 ok(0, "unexpected call\n");
1483 return E_NOTIMPL;
1486 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1488 ok(0, "unexpected call\n");
1489 return E_NOTIMPL;
1492 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1493 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1495 ok(0, "unexpected call\n");
1496 return E_NOTIMPL;
1499 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1501 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1503 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1504 *ppv = iface;
1505 return S_OK;
1508 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1509 if(impl_protex) {
1510 *ppv = iface;
1511 return S_OK;
1513 *ppv = NULL;
1514 return E_NOINTERFACE;
1517 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1518 *ppv = &InternetPriority;
1519 return S_OK;
1522 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1523 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1524 *ppv = NULL;
1525 return E_NOINTERFACE;
1528 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1529 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1530 *ppv = NULL;
1531 return E_NOINTERFACE;
1534 if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */
1535 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1536 *ppv = NULL;
1537 return E_NOINTERFACE;
1540 static DWORD WINAPI thread_proc(PVOID arg)
1542 HRESULT hres;
1544 memset(&protocoldata, -1, sizeof(protocoldata));
1546 prot_state = 0;
1548 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1549 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1550 BINDSTATUS_FINDINGRESOURCE, hostW);
1551 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1552 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1554 SET_EXPECT(ReportProgress_CONNECTING);
1555 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1556 BINDSTATUS_CONNECTING, winehq_ipW);
1557 CHECK_CALLED(ReportProgress_CONNECTING);
1558 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1560 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1561 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1562 BINDSTATUS_SENDINGREQUEST, NULL);
1563 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1564 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1566 prot_state = 1;
1567 SET_EXPECT(Switch);
1568 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1569 CHECK_CALLED(Switch);
1570 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1572 if(!short_read) {
1573 prot_state = 2;
1574 if(mimefilter_test)
1575 SET_EXPECT(MimeFilter_Switch);
1576 else
1577 SET_EXPECT(Switch);
1578 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1579 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1580 if(mimefilter_test)
1581 CHECK_CALLED(MimeFilter_Switch);
1582 else
1583 CHECK_CALLED(Switch);
1585 if(test_abort) {
1586 SetEvent(event_complete);
1587 return 0;
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 prot_state = 3;
1603 if(mimefilter_test)
1604 SET_EXPECT(MimeFilter_Switch);
1605 else
1606 SET_EXPECT(Switch);
1607 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1608 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1609 if(mimefilter_test)
1610 CHECK_CALLED(MimeFilter_Switch);
1611 else
1612 CHECK_CALLED(Switch);
1615 SetEvent(event_complete);
1617 return 0;
1620 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1622 BINDINFO bindinfo, exp_bindinfo;
1623 DWORD cbindf = 0;
1624 HRESULT hres;
1626 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1627 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1628 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1629 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1630 ok(!pi, "pi = %x\n", pi);
1632 if(binding_test)
1633 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1635 memset(&bindinfo, 0, sizeof(bindinfo));
1636 bindinfo.cbSize = sizeof(bindinfo);
1637 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1638 SET_EXPECT(GetBindInfo);
1639 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1640 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1641 CHECK_CALLED(GetBindInfo);
1642 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1643 cbindf, (bindf|BINDF_FROMURLMON));
1644 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1645 pReleaseBindInfo(&bindinfo);
1647 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1648 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1649 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1650 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1652 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1653 IServiceProvider *service_provider;
1654 IHttpNegotiate *http_negotiate;
1655 IHttpNegotiate2 *http_negotiate2;
1656 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1657 LPWSTR additional_headers = NULL;
1658 BYTE sec_id[100];
1659 DWORD fetched = 0, size = 100;
1660 DWORD tid;
1662 SET_EXPECT(GetBindString_USER_AGENT);
1663 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1664 &ua, 1, &fetched);
1665 CHECK_CALLED(GetBindString_USER_AGENT);
1666 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1667 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1668 ok(ua != NULL, "ua = %p\n", ua);
1669 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1670 CoTaskMemFree(ua);
1672 fetched = 256;
1673 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1674 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1675 accept_mimes, 256, &fetched);
1676 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1678 ok(hres == S_OK,
1679 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1680 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1681 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1682 CoTaskMemFree(accept_mimes[0]);
1684 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1685 (void**)&service_provider);
1686 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1688 SET_EXPECT(QueryService_HttpNegotiate);
1689 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1690 &IID_IHttpNegotiate, (void**)&http_negotiate);
1691 CHECK_CALLED(QueryService_HttpNegotiate);
1692 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1694 SET_EXPECT(BeginningTransaction);
1695 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1696 NULL, 0, &additional_headers);
1697 CHECK_CALLED(BeginningTransaction);
1698 IHttpNegotiate_Release(http_negotiate);
1699 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1700 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1702 SET_EXPECT(QueryService_HttpNegotiate);
1703 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1704 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1705 CHECK_CALLED(QueryService_HttpNegotiate);
1706 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1708 size = 512;
1709 SET_EXPECT(GetRootSecurityId);
1710 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1711 CHECK_CALLED(GetRootSecurityId);
1712 IHttpNegotiate2_Release(http_negotiate2);
1713 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1714 ok(size == 13, "size=%d\n", size);
1716 IServiceProvider_Release(service_provider);
1718 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1719 return;
1722 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1723 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1724 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1725 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1726 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1728 if(mimefilter_test) {
1729 SET_EXPECT(MimeFilter_CreateInstance);
1730 SET_EXPECT(MimeFilter_Start);
1731 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1733 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1734 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1735 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1736 ok(hres == S_OK,
1737 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1738 if(mimefilter_test) {
1739 CHECK_CALLED(MimeFilter_CreateInstance);
1740 CHECK_CALLED(MimeFilter_Start);
1741 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1742 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1743 }else {
1744 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1747 if(mimefilter_test)
1748 SET_EXPECT(MimeFilter_ReportData);
1749 else
1750 SET_EXPECT(ReportData);
1751 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1752 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1753 13, 13);
1754 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1755 if(mimefilter_test)
1756 CHECK_CALLED(MimeFilter_ReportData);
1757 else
1758 CHECK_CALLED(ReportData);
1760 if(tested_protocol == ITS_TEST) {
1761 SET_EXPECT(ReportData);
1762 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1763 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1764 CHECK_CALLED(ReportData);
1767 if(tested_protocol == BIND_TEST) {
1768 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1769 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1772 if(mimefilter_test)
1773 SET_EXPECT(MimeFilter_ReportResult);
1774 else
1775 SET_EXPECT(ReportResult);
1776 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1777 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1778 if(mimefilter_test)
1779 CHECK_CALLED(MimeFilter_ReportResult);
1780 else
1781 CHECK_CALLED(ReportResult);
1784 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1785 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1786 DWORD grfPI, HANDLE_PTR dwReserved)
1788 CHECK_EXPECT(Start);
1790 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1791 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1792 return S_OK;
1795 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1796 PROTOCOLDATA *pProtocolData)
1798 DWORD bscf = 0, pr;
1799 HRESULT hres;
1801 CHECK_EXPECT(Continue);
1803 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1804 if(!pProtocolData || tested_protocol == BIND_TEST)
1805 return S_OK;
1806 if(binding_test) {
1807 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1808 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1809 pProtocolData->grfFlags, protocoldata.grfFlags );
1810 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1811 pProtocolData->dwState, protocoldata.dwState );
1812 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1813 pProtocolData->pData, protocoldata.pData );
1814 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1815 pProtocolData->cbData, protocoldata.cbData );
1818 switch(prot_state) {
1819 case 1: {
1820 IServiceProvider *service_provider;
1821 IHttpNegotiate *http_negotiate;
1822 static const WCHAR header[] = {'?',0};
1824 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1825 (void**)&service_provider);
1826 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1828 SET_EXPECT(QueryService_HttpNegotiate);
1829 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1830 &IID_IHttpNegotiate, (void**)&http_negotiate);
1831 IServiceProvider_Release(service_provider);
1832 CHECK_CALLED(QueryService_HttpNegotiate);
1833 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1835 SET_EXPECT(OnResponse);
1836 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1837 IHttpNegotiate_Release(http_negotiate);
1838 CHECK_CALLED(OnResponse);
1839 IHttpNegotiate_Release(http_negotiate);
1840 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1842 if(mimefilter_test) {
1843 SET_EXPECT(MimeFilter_CreateInstance);
1844 SET_EXPECT(MimeFilter_Start);
1845 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1846 }else if(!(pi & PI_MIMEVERIFICATION)) {
1847 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1849 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1850 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1851 if(mimefilter_test) {
1852 CHECK_CALLED(MimeFilter_CreateInstance);
1853 CHECK_CALLED(MimeFilter_Start);
1854 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1855 }else if(!(pi & PI_MIMEVERIFICATION)) {
1856 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1858 ok(hres == S_OK,
1859 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1861 bscf |= BSCF_FIRSTDATANOTIFICATION;
1862 break;
1864 case 2:
1865 case 3:
1866 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1867 break;
1870 pr = prot_read;
1871 if(mimefilter_test)
1872 SET_EXPECT(MimeFilter_ReportData);
1873 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1874 if(pr < 200)
1875 SET_EXPECT(Read); /* checked in ReportData for short_read */
1876 if(pr == 200) {
1877 if(!mimefilter_test)
1878 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1879 SET_EXPECT(GetBindInfo);
1880 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1882 if(pr >= 200)
1883 SET_EXPECT(ReportData);
1884 }else {
1885 SET_EXPECT(ReportData);
1888 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1889 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1891 if(mimefilter_test) {
1892 SET_EXPECT(MimeFilter_ReportData);
1893 }else if(pi & PI_MIMEVERIFICATION) {
1894 if(!short_read && pr < 200)
1895 CHECK_CALLED(Read);
1896 if(pr == 200) {
1897 CLEAR_CALLED(GetBindInfo); /* IE9 */
1898 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1900 }else {
1901 CHECK_CALLED(ReportData);
1904 if(prot_state == 3)
1905 prot_state = 4;
1907 return S_OK;
1910 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1912 CHECK_EXPECT(Terminate);
1913 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1914 return S_OK;
1917 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1918 ULONG cb, ULONG *pcbRead)
1920 if(read_report_data)
1921 CHECK_EXPECT2(Read2);
1923 if(mimefilter_test || short_read) {
1924 if(!read_report_data)
1925 CHECK_EXPECT2(Read);
1926 }else if((pi & PI_MIMEVERIFICATION)) {
1927 if(!read_report_data)
1928 CHECK_EXPECT2(Read);
1930 if(prot_read < 300) {
1931 ok(pv != expect_pv, "pv == expect_pv\n");
1932 if(prot_read < 300)
1933 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1934 else
1935 ok(cb == 700, "cb=%d\n", cb);
1936 }else {
1937 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1939 }else {
1940 if(!read_report_data)
1941 CHECK_EXPECT(Read);
1943 ok(pv == expect_pv, "pv != expect_pv\n");
1944 ok(cb == 1000, "cb=%d\n", cb);
1945 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1947 ok(pcbRead != NULL, "pcbRead == NULL\n");
1949 if(prot_state == 3 || (short_read && prot_state != 4)) {
1950 HRESULT hres;
1952 prot_state = 4;
1953 if(short_read) {
1954 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1955 SET_EXPECT(GetBindInfo);
1956 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1958 if(mimefilter_test)
1959 SET_EXPECT(MimeFilter_ReportData);
1960 else if(direct_read)
1961 SET_EXPECT(ReportData2);
1962 read_report_data++;
1963 hres = IInternetProtocolSink_ReportData(binding_sink,
1964 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1965 read_report_data--;
1966 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1967 if(short_read) {
1968 CLEAR_CALLED(GetBindInfo); /* IE9 */
1969 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1971 if(mimefilter_test)
1972 CHECK_CALLED(MimeFilter_ReportData);
1973 else if(direct_read)
1974 CHECK_CALLED(ReportData2);
1976 if(mimefilter_test)
1977 SET_EXPECT(MimeFilter_ReportResult);
1978 else
1979 SET_EXPECT(ReportResult);
1980 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1981 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1982 if(mimefilter_test)
1983 CHECK_CALLED(MimeFilter_ReportResult);
1984 else
1985 CHECK_CALLED(ReportResult);
1987 if(cb > 100)
1988 cb = 100;
1989 memset(pv, 'x', cb);
1990 if(cb>6)
1991 memcpy(pv, "gif87a", 6);
1992 prot_read += *pcbRead = cb;
1993 return S_OK;
1996 if(prot_state == 4) {
1997 *pcbRead = 0;
1998 return S_FALSE;
2001 if((async_read_pending = !async_read_pending)) {
2002 *pcbRead = 0;
2003 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
2006 if(cb > 100)
2007 cb = 100;
2008 memset(pv, 'x', cb);
2009 if(cb>6)
2010 memcpy(pv, "gif87a", 6);
2011 prot_read += *pcbRead = cb;
2012 return S_OK;
2015 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2017 CHECK_EXPECT(LockRequest);
2018 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2019 return S_OK;
2022 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2024 CHECK_EXPECT(UnlockRequest);
2025 return S_OK;
2028 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2029 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2030 DWORD grfPI, HANDLE *dwReserved)
2032 CHECK_EXPECT(StartEx);
2033 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2034 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2035 return S_OK;
2038 static const IInternetProtocolExVtbl ProtocolVtbl = {
2039 ProtocolEmul_QueryInterface,
2040 Protocol_AddRef,
2041 Protocol_Release,
2042 ProtocolEmul_Start,
2043 ProtocolEmul_Continue,
2044 Protocol_Abort,
2045 ProtocolEmul_Terminate,
2046 Protocol_Suspend,
2047 Protocol_Resume,
2048 ProtocolEmul_Read,
2049 Protocol_Seek,
2050 ProtocolEmul_LockRequest,
2051 ProtocolEmul_UnlockRequest,
2052 ProtocolEmul_StartEx
2055 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2057 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2059 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2060 *ppv = iface;
2061 return S_OK;
2064 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2065 *ppv = &mime_protocol_sink;
2066 return S_OK;
2069 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2070 *ppv = NULL;
2071 return E_NOINTERFACE;
2074 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2075 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2076 DWORD grfPI, HANDLE_PTR dwReserved)
2078 PROTOCOLFILTERDATA *data;
2079 LPOLESTR url_str = NULL;
2080 DWORD fetched = 0;
2081 BINDINFO bindinfo;
2082 DWORD cbindf = 0;
2083 HRESULT hres;
2085 CHECK_EXPECT(MimeFilter_Start);
2087 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2088 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2089 ok(dwReserved, "dwReserved == 0\n");
2090 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2091 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2093 if(binding_test) {
2094 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2095 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2096 }else {
2097 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2098 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2101 data = (void*)dwReserved;
2102 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2103 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2104 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2105 ok(!data->pUnk, "data->pUnk != NULL\n");
2106 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2107 if(binding_test) {
2108 IInternetProtocolSink *prot_sink;
2110 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2111 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2112 IInternetProtocolSink_Release(prot_sink);
2114 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2116 filtered_protocol = data->pProtocol;
2117 IInternetProtocol_AddRef(filtered_protocol);
2118 }else {
2119 IInternetProtocol *prot;
2121 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2122 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2123 IInternetProtocol_Release(prot);
2125 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2128 filtered_sink = pOIProtSink;
2130 SET_EXPECT(ReportProgress_DECODING);
2131 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2132 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2133 CHECK_CALLED(ReportProgress_DECODING);
2135 SET_EXPECT(GetBindInfo);
2136 memset(&bindinfo, 0, sizeof(bindinfo));
2137 bindinfo.cbSize = sizeof(bindinfo);
2138 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2139 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2140 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2141 CHECK_CALLED(GetBindInfo);
2143 SET_EXPECT(GetBindString_URL);
2144 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2145 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2146 ok(fetched == 1, "fetched = %d\n", fetched);
2147 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2148 CoTaskMemFree(url_str);
2149 CHECK_CALLED(GetBindString_URL);
2151 return S_OK;
2154 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2155 PROTOCOLDATA *pProtocolData)
2157 CHECK_EXPECT(MimeFilter_Continue);
2158 return E_NOTIMPL;
2161 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2163 HRESULT hres;
2165 CHECK_EXPECT(MimeFilter_Terminate);
2167 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2169 SET_EXPECT(Terminate);
2170 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2171 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2172 CHECK_CALLED(Terminate);
2174 return S_OK;
2177 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2178 ULONG cb, ULONG *pcbRead)
2180 BYTE buf[2096];
2181 DWORD read = 0;
2182 HRESULT hres;
2184 CHECK_EXPECT(MimeFilter_Read);
2186 ok(pv != NULL, "pv == NULL\n");
2187 ok(cb != 0, "cb == 0\n");
2188 ok(pcbRead != NULL, "pcbRead == NULL\n");
2190 if(read_report_data)
2191 SET_EXPECT(Read2);
2192 else
2193 SET_EXPECT(Read);
2194 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2195 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2196 if(read_report_data)
2197 CHECK_CALLED(Read2);
2198 else
2199 CHECK_CALLED(Read);
2201 if(pcbRead) {
2202 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2203 *pcbRead = read;
2206 memset(pv, 'x', read);
2207 return hres;
2210 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2212 HRESULT hres;
2214 CHECK_EXPECT(MimeFilter_LockRequest);
2216 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2218 SET_EXPECT(LockRequest);
2219 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2220 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2221 CHECK_CALLED(LockRequest);
2223 return S_OK;
2226 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2228 HRESULT hres;
2230 CHECK_EXPECT(MimeFilter_UnlockRequest);
2232 SET_EXPECT(UnlockRequest);
2233 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2234 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2235 CHECK_CALLED(UnlockRequest);
2237 return S_OK;
2240 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2241 MimeProtocol_QueryInterface,
2242 Protocol_AddRef,
2243 Protocol_Release,
2244 MimeProtocol_Start,
2245 Protocol_Continue,
2246 Protocol_Abort,
2247 MimeProtocol_Terminate,
2248 Protocol_Suspend,
2249 Protocol_Resume,
2250 MimeProtocol_Read,
2251 Protocol_Seek,
2252 MimeProtocol_LockRequest,
2253 MimeProtocol_UnlockRequest
2256 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2258 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2260 ok(0, "unexpected call\n");
2261 return E_NOINTERFACE;
2264 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2266 return 2;
2269 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2271 return 1;
2274 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2275 REFIID riid, void **ppv)
2277 CHECK_EXPECT(CreateInstance);
2279 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2280 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2281 ok(ppv != NULL, "ppv == NULL\n");
2283 *ppv = &Protocol;
2284 return S_OK;
2287 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2289 ok(0, "unexpected call\n");
2290 return S_OK;
2293 static const IClassFactoryVtbl ClassFactoryVtbl = {
2294 ClassFactory_QueryInterface,
2295 ClassFactory_AddRef,
2296 ClassFactory_Release,
2297 ClassFactory_CreateInstance,
2298 ClassFactory_LockServer
2301 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2303 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2305 CHECK_EXPECT(MimeFilter_CreateInstance);
2307 ok(!outer, "outer = %p\n", outer);
2308 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2310 *ppv = &MimeProtocol;
2311 return S_OK;
2314 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2315 ClassFactory_QueryInterface,
2316 ClassFactory_AddRef,
2317 ClassFactory_Release,
2318 MimeFilter_CreateInstance,
2319 ClassFactory_LockServer
2322 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2324 #define TEST_BINDING 0x0001
2325 #define TEST_FILTER 0x0002
2326 #define TEST_FIRST_HTTP 0x0004
2327 #define TEST_DIRECT_READ 0x0008
2328 #define TEST_POST 0x0010
2329 #define TEST_EMULATEPROT 0x0020
2330 #define TEST_SHORT_READ 0x0040
2331 #define TEST_REDIRECT 0x0080
2332 #define TEST_ABORT 0x0100
2333 #define TEST_ASYNCREQ 0x0200
2334 #define TEST_USEIURI 0x0400
2335 #define TEST_IMPLPROTEX 0x0800
2336 #define TEST_EMPTY 0x1000
2337 #define TEST_NOMIME 0x2000
2338 #define TEST_FROMCACHE 0x4000
2340 static void register_filter(BOOL do_register)
2342 IInternetSession *session;
2343 HRESULT hres;
2345 hres = pCoInternetGetSession(0, &session, 0);
2346 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2348 if(do_register) {
2349 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2350 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2351 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2352 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2353 }else {
2354 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2355 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2356 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2357 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2360 IInternetSession_Release(session);
2363 static void init_test(int prot, DWORD flags)
2365 tested_protocol = prot;
2366 binding_test = (flags & TEST_BINDING) != 0;
2367 first_data_notif = TRUE;
2368 prot_read = 0;
2369 prot_state = 0;
2370 async_read_pending = TRUE;
2371 mimefilter_test = (flags & TEST_FILTER) != 0;
2372 no_mime = (flags & TEST_NOMIME) != 0;
2373 filter_state = 0;
2374 post_stream_read = 0;
2375 ResetEvent(event_complete);
2376 ResetEvent(event_complete2);
2377 ResetEvent(event_continue);
2378 ResetEvent(event_continue_done);
2379 async_protocol = binding_protocol = filtered_protocol = NULL;
2380 filtered_sink = NULL;
2381 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2382 first_data_notif = TRUE;
2383 state = STATE_CONNECTING;
2384 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2385 direct_read = (flags & TEST_DIRECT_READ) != 0;
2386 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2387 wait_for_switch = TRUE;
2388 short_read = (flags & TEST_SHORT_READ) != 0;
2389 http_post_test = TYMED_NULL;
2390 test_redirect = (flags & TEST_REDIRECT) != 0;
2391 test_abort = (flags & TEST_ABORT) != 0;
2392 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2393 empty_file = (flags & TEST_EMPTY) != 0;
2394 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2396 register_filter(mimefilter_test);
2399 static void test_priority(IInternetProtocol *protocol)
2401 IInternetPriority *priority;
2402 LONG pr;
2403 HRESULT hres;
2405 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2406 (void**)&priority);
2407 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2408 if(FAILED(hres))
2409 return;
2411 hres = IInternetPriority_GetPriority(priority, &pr);
2412 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2413 ok(pr == 0, "pr=%d, expected 0\n", pr);
2415 hres = IInternetPriority_SetPriority(priority, 1);
2416 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2418 hres = IInternetPriority_GetPriority(priority, &pr);
2419 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2420 ok(pr == 1, "pr=%d, expected 1\n", pr);
2422 IInternetPriority_Release(priority);
2425 static void test_early_abort(const CLSID *clsid)
2427 IInternetProtocol *protocol;
2428 HRESULT hres;
2430 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2431 &IID_IInternetProtocol, (void**)&protocol);
2432 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2434 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2435 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2437 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2438 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2440 IInternetProtocol_Release(protocol);
2443 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2444 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2446 HRESULT hres;
2448 SET_EXPECT(GetBindInfo);
2449 if(!(bindf & BINDF_FROMURLMON))
2450 SET_EXPECT(ReportProgress_DIRECTBIND);
2451 if(is_first) {
2452 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2453 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2454 if(bindf & BINDF_FROMURLMON)
2455 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2456 else
2457 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2459 SET_EXPECT(ReportData);
2460 if(is_first)
2461 SET_EXPECT(ReportResult);
2463 expect_hrResult = S_OK;
2465 if(protocolex) {
2466 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2467 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2468 }else {
2469 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2470 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2471 win_skip("Start failed\n");
2472 return FALSE;
2474 ok(hres == S_OK, "Start failed: %08x\n", hres);
2477 CHECK_CALLED(GetBindInfo);
2478 if(!(bindf & BINDF_FROMURLMON))
2479 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2480 if(is_first) {
2481 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2482 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2483 if(bindf & BINDF_FROMURLMON)
2484 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2485 else
2486 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2488 CHECK_CALLED(ReportData);
2489 if(is_first)
2490 CHECK_CALLED(ReportResult);
2492 return TRUE;
2495 static void test_file_protocol_url(LPCWSTR url)
2497 IInternetProtocolInfo *protocol_info;
2498 IUnknown *unk;
2499 IClassFactory *factory;
2500 IInternetProtocol *protocol;
2501 BYTE buf[512];
2502 ULONG cb;
2503 HRESULT hres;
2505 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2506 &IID_IUnknown, (void**)&unk);
2507 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2508 if(FAILED(hres))
2509 return;
2511 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2512 ok(hres == E_NOINTERFACE,
2513 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2515 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2516 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2517 IUnknown_Release(unk);
2518 if(FAILED(hres))
2519 return;
2521 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2522 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2524 if(SUCCEEDED(hres)) {
2525 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2526 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2527 ok(hres == S_OK, "Read failed: %08x\n", hres);
2528 ok(cb == 2, "cb=%u expected 2\n", cb);
2529 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2530 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2531 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2532 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2533 ok(cb == 0, "cb=%u expected 0\n", cb);
2534 hres = IInternetProtocol_UnlockRequest(protocol);
2535 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2538 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2539 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2540 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2541 hres = IInternetProtocol_LockRequest(protocol, 0);
2542 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2543 hres = IInternetProtocol_UnlockRequest(protocol);
2544 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2547 IInternetProtocol_Release(protocol);
2550 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2551 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2552 if(SUCCEEDED(hres)) {
2553 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2554 hres = IInternetProtocol_LockRequest(protocol, 0);
2555 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2556 hres = IInternetProtocol_Terminate(protocol, 0);
2557 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2558 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2559 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2560 hres = IInternetProtocol_UnlockRequest(protocol);
2561 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2562 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2563 ok(hres == S_OK, "Read failed: %08x\n", hres);
2564 hres = IInternetProtocol_Terminate(protocol, 0);
2565 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2568 IInternetProtocol_Release(protocol);
2571 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2572 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2573 if(SUCCEEDED(hres)) {
2574 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2575 hres = IInternetProtocol_Terminate(protocol, 0);
2576 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2577 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2578 ok(hres == S_OK, "Read failed: %08x\n", hres);
2579 ok(cb == 2, "cb=%u expected 2\n", cb);
2582 IInternetProtocol_Release(protocol);
2585 if(pCreateUri) {
2586 IInternetProtocolEx *protocolex;
2587 IUri *uri;
2589 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2590 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2592 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2593 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2595 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2596 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2597 ok(hres == S_OK, "Read failed: %08x\n", hres);
2598 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2599 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2600 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2601 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2604 IUri_Release(uri);
2605 IInternetProtocolEx_Release(protocolex);
2607 hres = pCreateUri(url, 0, 0, &uri);
2608 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2610 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2611 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2613 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2614 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2615 ok(hres == S_OK, "Read failed: %08x\n", hres);
2616 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2617 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2618 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2619 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2622 IUri_Release(uri);
2623 IInternetProtocolEx_Release(protocolex);
2624 }else {
2625 win_skip("Skipping file protocol StartEx tests\n");
2628 IClassFactory_Release(factory);
2631 static void test_file_protocol_fail(void)
2633 IInternetProtocol *protocol;
2634 HRESULT hres;
2636 static const WCHAR index_url2[] =
2637 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2639 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2640 &IID_IInternetProtocol, (void**)&protocol);
2641 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2642 if(FAILED(hres))
2643 return;
2645 SET_EXPECT(GetBindInfo);
2646 expect_hrResult = MK_E_SYNTAX;
2647 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2648 ok(hres == MK_E_SYNTAX ||
2649 hres == E_INVALIDARG,
2650 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2651 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2653 SET_EXPECT(GetBindInfo);
2654 if(!(bindf & BINDF_FROMURLMON))
2655 SET_EXPECT(ReportProgress_DIRECTBIND);
2656 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2657 SET_EXPECT(ReportResult);
2658 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2659 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2660 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2661 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2662 CHECK_CALLED(GetBindInfo);
2663 if(!(bindf & BINDF_FROMURLMON))
2664 CHECK_CALLED(ReportProgress_DIRECTBIND);
2665 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2666 CHECK_CALLED(ReportResult);
2668 IInternetProtocol_Release(protocol);
2670 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2671 &IID_IInternetProtocol, (void**)&protocol);
2672 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2673 if(FAILED(hres))
2674 return;
2676 SET_EXPECT(GetBindInfo);
2677 if(!(bindf & BINDF_FROMURLMON))
2678 SET_EXPECT(ReportProgress_DIRECTBIND);
2679 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2680 SET_EXPECT(ReportResult);
2681 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2683 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2684 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2685 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2686 CHECK_CALLED(GetBindInfo);
2687 if(!(bindf & BINDF_FROMURLMON))
2688 CHECK_CALLED(ReportProgress_DIRECTBIND);
2689 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2690 CHECK_CALLED(ReportResult);
2692 SET_EXPECT(GetBindInfo);
2693 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2694 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2695 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2697 SET_EXPECT(GetBindInfo);
2698 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2699 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2700 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2702 IInternetProtocol_Release(protocol);
2705 static void test_file_protocol(void) {
2706 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2707 DWORD size;
2708 ULONG len;
2709 HANDLE file;
2711 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2712 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2713 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2714 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2715 static const char html_doc[] = "<HTML></HTML>";
2717 trace("Testing file protocol...\n");
2718 init_test(FILE_TEST, 0);
2720 SetLastError(0xdeadbeef);
2721 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2722 FILE_ATTRIBUTE_NORMAL, NULL);
2723 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2724 if(file == INVALID_HANDLE_VALUE)
2725 return;
2726 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2727 CloseHandle(file);
2729 file_name = wszIndexHtml;
2730 bindf = 0;
2731 test_file_protocol_url(index_url);
2732 bindf = BINDF_FROMURLMON;
2733 test_file_protocol_url(index_url);
2734 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2735 test_file_protocol_url(index_url);
2737 memcpy(buf, wszFile, sizeof(wszFile));
2738 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2739 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2740 buf[len++] = '\\';
2741 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2743 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2744 bindf = 0;
2745 test_file_protocol_url(buf);
2746 bindf = BINDF_FROMURLMON;
2747 test_file_protocol_url(buf);
2749 memcpy(buf, wszFile2, sizeof(wszFile2));
2750 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2751 file_name_buf[len++] = '\\';
2752 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2753 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2754 file_name = file_name_buf;
2755 bindf = 0;
2756 test_file_protocol_url(buf);
2757 bindf = BINDF_FROMURLMON;
2758 test_file_protocol_url(buf);
2760 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2761 test_file_protocol_url(buf);
2763 memcpy(buf, wszFile3, sizeof(wszFile3));
2764 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2765 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2766 buf[len++] = '\\';
2767 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2769 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2770 bindf = 0;
2771 test_file_protocol_url(buf);
2772 bindf = BINDF_FROMURLMON;
2773 test_file_protocol_url(buf);
2775 memcpy(buf, wszFile4, sizeof(wszFile4));
2776 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2777 file_name_buf[len++] = '\\';
2778 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2779 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2780 file_name = file_name_buf;
2781 bindf = 0;
2782 test_file_protocol_url(buf);
2783 bindf = BINDF_FROMURLMON;
2784 test_file_protocol_url(buf);
2786 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2787 test_file_protocol_url(buf);
2789 DeleteFileW(wszIndexHtml);
2791 bindf = 0;
2792 test_file_protocol_fail();
2793 bindf = BINDF_FROMURLMON;
2794 test_file_protocol_fail();
2797 static void create_cache_entry(const WCHAR *urlw)
2799 FILETIME now, tomorrow, yesterday;
2800 char file_path[MAX_PATH];
2801 BYTE content[1000];
2802 ULARGE_INTEGER li;
2803 const char *url;
2804 HANDLE file;
2805 DWORD size;
2806 unsigned i;
2807 BOOL res;
2809 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2811 trace("Testing cache read...\n");
2813 url = w2a(urlw);
2815 for(i = 0; i < sizeof(content); i++)
2816 content[i] = '0' + (i%10);
2818 GetSystemTimeAsFileTime(&now);
2819 li.u.HighPart = now.dwHighDateTime;
2820 li.u.LowPart = now.dwLowDateTime;
2821 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2822 tomorrow.dwHighDateTime = li.u.HighPart;
2823 tomorrow.dwLowDateTime = li.u.LowPart;
2824 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2825 yesterday.dwHighDateTime = li.u.HighPart;
2826 yesterday.dwLowDateTime = li.u.LowPart;
2828 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2829 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2831 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2832 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2834 WriteFile(file, content, sizeof(content), &size, NULL);
2835 CloseHandle(file);
2837 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2838 cache_headers, sizeof(cache_headers)-1, "", 0);
2839 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2842 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2844 static BOOL got_user_agent = FALSE;
2845 IUri *uri = NULL;
2846 HRESULT hres;
2848 if(use_iuri && pCreateUri) {
2849 hres = pCreateUri(url, 0, 0, &uri);
2850 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2853 SET_EXPECT(GetBindInfo);
2854 if (!(bindf & BINDF_FROMURLMON))
2855 SET_EXPECT(ReportProgress_DIRECTBIND);
2856 if(!got_user_agent)
2857 SET_EXPECT(GetBindString_USER_AGENT);
2858 SET_EXPECT(GetBindString_ROOTDOC_URL);
2859 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2860 SET_EXPECT(QueryService_HttpNegotiate);
2861 SET_EXPECT(BeginningTransaction);
2862 SET_EXPECT(GetRootSecurityId);
2863 if(http_post_test) {
2864 SET_EXPECT(GetBindString_POST_COOKIE);
2865 if(http_post_test == TYMED_ISTREAM)
2866 SET_EXPECT(Stream_Seek);
2868 if(bind_from_cache) {
2869 SET_EXPECT(OnResponse);
2870 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2871 SET_EXPECT(ReportData);
2874 if(uri) {
2875 IInternetProtocolEx *protocolex;
2877 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2878 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2880 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2881 ok(hres == S_OK, "Start failed: %08x\n", hres);
2883 IInternetProtocolEx_Release(protocolex);
2884 IUri_Release(uri);
2885 }else {
2886 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2887 ok(hres == S_OK, "Start failed: %08x\n", hres);
2889 if(FAILED(hres))
2890 return FALSE;
2892 CHECK_CALLED(GetBindInfo);
2893 if (!(bindf & BINDF_FROMURLMON))
2894 CHECK_CALLED(ReportProgress_DIRECTBIND);
2895 if (!got_user_agent)
2897 CHECK_CALLED(GetBindString_USER_AGENT);
2898 got_user_agent = TRUE;
2900 CLEAR_CALLED(GetBindString_ROOTDOC_URL); /* New in IE11 */
2901 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2902 CHECK_CALLED(QueryService_HttpNegotiate);
2903 CHECK_CALLED(BeginningTransaction);
2904 /* GetRootSecurityId called on WinXP but not on Win98 */
2905 CLEAR_CALLED(GetRootSecurityId);
2906 if(http_post_test) {
2907 CHECK_CALLED(GetBindString_POST_COOKIE);
2908 if(http_post_test == TYMED_ISTREAM)
2909 CHECK_CALLED(Stream_Seek);
2911 if(bind_from_cache) {
2912 CHECK_CALLED(OnResponse);
2913 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2914 CHECK_CALLED(ReportData);
2917 return TRUE;
2920 static void test_protocol_terminate(IInternetProtocol *protocol)
2922 BYTE buf[3600];
2923 DWORD cb;
2924 HRESULT hres;
2926 hres = IInternetProtocol_LockRequest(protocol, 0);
2927 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2929 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2930 ok(hres == (test_abort ? S_OK : S_FALSE), "Read failed: %08x\n", hres);
2932 hres = IInternetProtocol_Terminate(protocol, 0);
2933 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2935 /* This wait is to give the internet handles being freed in Terminate
2936 * enough time to actually terminate in all cases. Internet handles
2937 * terminate asynchronously and native reuses the main InternetOpen
2938 * handle. The only case in which this seems to be necessary is on
2939 * wine with native wininet and urlmon, resulting in the next time
2940 * test_http_protocol_url being called the first data notification actually
2941 * being an extra last data notification from the previous connection
2942 * about once out of every ten times. */
2943 Sleep(100);
2945 hres = IInternetProtocol_UnlockRequest(protocol);
2946 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2949 static void test_http_info(IInternetProtocol *protocol)
2951 IWinInetHttpInfo *info;
2952 HRESULT hres;
2954 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2955 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2957 /* TODO */
2959 IWinInetHttpInfo_Release(info);
2962 /* is_first refers to whether this is the first call to this function
2963 * _for this url_ */
2964 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
2966 IInternetProtocolInfo *protocol_info;
2967 IClassFactory *factory;
2968 IUnknown *unk;
2969 HRESULT hres;
2971 init_test(prot, flags);
2972 http_url = url;
2973 http_post_test = tymed;
2975 if(flags & TEST_FROMCACHE)
2976 create_cache_entry(url);
2978 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
2979 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
2980 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2981 if(FAILED(hres))
2982 return;
2984 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2985 ok(hres == E_NOINTERFACE,
2986 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
2987 hres);
2989 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2990 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2991 IUnknown_Release(unk);
2992 if(FAILED(hres))
2993 return;
2995 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
2996 (void**)&async_protocol);
2997 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2998 if(SUCCEEDED(hres)) {
2999 BYTE buf[3600];
3000 DWORD cb;
3001 ULONG ref;
3003 test_priority(async_protocol);
3004 test_http_info(async_protocol);
3006 SET_EXPECT(ReportProgress_COOKIE_SENT);
3007 if(http_is_first) {
3008 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3009 SET_EXPECT(ReportProgress_CONNECTING);
3011 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3012 if(test_redirect)
3013 SET_EXPECT(ReportProgress_REDIRECTING);
3014 SET_EXPECT(ReportProgress_PROXYDETECTING);
3015 if(prot == HTTP_TEST)
3016 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3017 else
3018 SET_EXPECT(QueryService_HttpSecurity);
3019 if(!(bindf & BINDF_FROMURLMON)) {
3020 SET_EXPECT(OnResponse);
3021 SET_EXPECT(ReportProgress_RAWMIMETYPE);
3022 SET_EXPECT(ReportData);
3023 } else {
3024 SET_EXPECT(Switch);
3027 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3028 IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3029 IInternetProtocol_Release(async_protocol);
3030 return;
3033 if(!direct_read && !test_abort && !bind_from_cache)
3034 SET_EXPECT(ReportResult);
3035 expect_hrResult = test_abort ? E_ABORT : S_OK;
3037 if(direct_read) {
3038 SET_EXPECT(Switch);
3039 while(wait_for_switch) {
3040 ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3041 CHECK_CALLED(Switch); /* Set in ReportData */
3042 call_continue(&continue_protdata);
3043 SetEvent(event_continue_done);
3045 }else if(bind_from_cache) {
3046 BYTE buf[1500];
3048 hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3049 ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3051 SET_EXPECT(ReportResult);
3052 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3053 ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3054 CHECK_CALLED(ReportResult);
3056 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3057 ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3058 }else {
3059 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3060 ok((hres == E_PENDING && cb==0) ||
3061 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3063 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3064 if(bindf & BINDF_FROMURLMON)
3065 CHECK_CALLED(Switch);
3066 else
3067 CHECK_CALLED(ReportData);
3068 if(prot == HTTPS_TEST)
3069 CLEAR_CALLED(QueryService_HttpSecurity);
3071 while(1) {
3072 if(bindf & BINDF_FROMURLMON)
3073 SET_EXPECT(Switch);
3074 else
3075 SET_EXPECT(ReportData);
3076 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3077 if(hres == E_PENDING) {
3078 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3079 ok((hres == E_PENDING && cb==0) ||
3080 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3081 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3082 if(bindf & BINDF_FROMURLMON)
3083 CHECK_CALLED(Switch);
3084 else
3085 CHECK_CALLED(ReportData);
3087 if(test_abort) {
3088 HRESULT hres;
3090 SET_EXPECT(ReportResult);
3091 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3092 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3093 CHECK_CALLED(ReportResult);
3095 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3096 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3097 break;
3099 }else {
3100 if(bindf & BINDF_FROMURLMON)
3101 CHECK_NOT_CALLED(Switch);
3102 else
3103 CHECK_NOT_CALLED(ReportData);
3104 if(cb == 0) break;
3107 if(!test_abort) {
3108 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3109 CHECK_CALLED(ReportResult);
3112 if(prot == HTTPS_TEST)
3113 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3115 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3116 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3118 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3119 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3121 test_protocol_terminate(async_protocol);
3123 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3124 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3126 ref = IInternetProtocol_Release(async_protocol);
3127 ok(!ref, "ref=%x\n", ref);
3130 IClassFactory_Release(factory);
3132 if(flags & TEST_FROMCACHE) {
3133 BOOL res;
3135 res = DeleteUrlCacheEntryW(url);
3136 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3140 static void test_http_protocol(void)
3142 static const WCHAR posttest_url[] =
3143 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3144 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3145 static const WCHAR redirect_url[] =
3146 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3147 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3148 static const WCHAR winetest_url[] =
3149 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3150 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3151 static const WCHAR empty_url[] =
3152 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3153 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3154 static const WCHAR cache_only_url[] =
3155 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3156 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3159 trace("Testing http protocol (not from urlmon)...\n");
3160 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3161 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3163 trace("Testing http protocol (from urlmon)...\n");
3164 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3165 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3167 trace("Testing http protocol (to file)...\n");
3168 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3169 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3171 trace("Testing http protocol (post data)...\n");
3172 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3173 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3175 trace("Testing http protocol (post data stream)...\n");
3176 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3178 trace("Testing http protocol (direct read)...\n");
3179 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3180 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3182 trace("Testing http protocol (redirected)...\n");
3183 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3184 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3186 trace("Testing http protocol empty file...\n");
3187 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3188 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3190 /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3191 * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3192 * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3193 * tests work on Windows and have them around for the future.
3195 if(broken(1)) {
3196 trace("Testing http protocol (from cache)...\n");
3197 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3198 test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3201 trace("Testing http protocol abort...\n");
3202 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3203 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3205 test_early_abort(&CLSID_HttpProtocol);
3206 test_early_abort(&CLSID_HttpSProtocol);
3209 static void test_https_protocol(void)
3211 static const WCHAR https_winehq_url[] =
3212 {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3213 't','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
3215 trace("Testing https protocol (from urlmon)...\n");
3216 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3217 test_http_protocol_url(https_winehq_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3221 static void test_ftp_protocol(void)
3223 IInternetProtocolInfo *protocol_info;
3224 IClassFactory *factory;
3225 IUnknown *unk;
3226 BYTE buf[4096];
3227 ULONG ref;
3228 DWORD cb;
3229 HRESULT hres;
3231 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3232 '/','p','u','b','/','o','t','h','e','r','/',
3233 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3235 trace("Testing ftp protocol...\n");
3237 init_test(FTP_TEST, 0);
3239 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3240 state = STATE_STARTDOWNLOADING;
3241 expect_hrResult = E_PENDING;
3243 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3244 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3245 if(FAILED(hres))
3246 return;
3248 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3249 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3251 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3252 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3253 IUnknown_Release(unk);
3254 if(FAILED(hres))
3255 return;
3257 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3258 (void**)&async_protocol);
3259 IClassFactory_Release(factory);
3260 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3262 test_priority(async_protocol);
3263 test_http_info(async_protocol);
3265 SET_EXPECT(GetBindInfo);
3266 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3267 SET_EXPECT(ReportProgress_CONNECTING);
3268 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3269 SET_EXPECT(Switch);
3271 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
3272 ok(hres == S_OK, "Start failed: %08x\n", hres);
3273 CHECK_CALLED(GetBindInfo);
3275 SET_EXPECT(ReportResult);
3277 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3278 ok((hres == E_PENDING && cb==0) ||
3279 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3281 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3283 while(1) {
3284 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3285 if(hres == E_PENDING)
3287 DWORD ret = WaitForSingleObject(event_complete, 90000);
3288 ok( ret == WAIT_OBJECT_0, "wait timed out\n" );
3289 if (ret != WAIT_OBJECT_0) break;
3291 else
3292 if(cb == 0) break;
3295 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3296 CHECK_CALLED(ReportResult);
3297 CHECK_CALLED(Switch);
3299 test_protocol_terminate(async_protocol);
3301 if(pCreateUri) {
3302 IInternetProtocolEx *protocolex;
3304 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3305 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3306 IInternetProtocolEx_Release(protocolex);
3309 ref = IInternetProtocol_Release(async_protocol);
3310 ok(!ref, "ref=%d\n", ref);
3312 test_early_abort(&CLSID_FtpProtocol);
3315 static void test_gopher_protocol(void)
3317 IInternetProtocolInfo *protocol_info;
3318 IClassFactory *factory;
3319 IUnknown *unk;
3320 HRESULT hres;
3322 trace("Testing gopher protocol...\n");
3324 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3325 ok(hres == S_OK ||
3326 broken(hres == REGDB_E_CLASSNOTREG || hres == CLASS_E_CLASSNOTAVAILABLE), /* Gopher protocol has been removed as of Vista */
3327 "CoGetClassObject failed: %08x\n", hres);
3328 if(FAILED(hres))
3329 return;
3331 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3332 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3334 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3335 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3336 IUnknown_Release(unk);
3337 if(FAILED(hres))
3338 return;
3340 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3341 (void**)&async_protocol);
3342 IClassFactory_Release(factory);
3343 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3345 test_priority(async_protocol);
3347 IInternetProtocol_Release(async_protocol);
3349 test_early_abort(&CLSID_GopherProtocol);
3352 static void test_mk_protocol(void)
3354 IInternetProtocolInfo *protocol_info;
3355 IInternetProtocol *protocol;
3356 IClassFactory *factory;
3357 IUnknown *unk;
3358 HRESULT hres;
3360 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
3361 ':',':','/','t','e','s','t','.','h','t','m','l',0};
3362 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
3364 trace("Testing mk protocol...\n");
3365 init_test(MK_TEST, 0);
3367 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
3368 &IID_IUnknown, (void**)&unk);
3369 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3371 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3372 ok(hres == E_NOINTERFACE,
3373 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3374 hres);
3376 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3377 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3378 IUnknown_Release(unk);
3379 if(FAILED(hres))
3380 return;
3382 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3383 (void**)&protocol);
3384 IClassFactory_Release(factory);
3385 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3387 SET_EXPECT(GetBindInfo);
3388 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
3389 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
3390 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
3391 CLEAR_CALLED(GetBindInfo);
3393 SET_EXPECT(GetBindInfo);
3394 SET_EXPECT(ReportProgress_DIRECTBIND);
3395 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3396 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3397 SET_EXPECT(ReportResult);
3398 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3400 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
3401 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
3402 hres == INET_E_INVALID_URL, /* win2k3 */
3403 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
3405 if (hres == INET_E_RESOURCE_NOT_FOUND) {
3406 CHECK_CALLED(GetBindInfo);
3407 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3408 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3409 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3410 CHECK_CALLED(ReportResult);
3411 }else {
3412 CLEAR_CALLED(GetBindInfo);
3413 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3414 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3415 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3416 CLEAR_CALLED(ReportResult);
3419 IInternetProtocol_Release(protocol);
3422 static void test_CreateBinding(void)
3424 IInternetProtocol *protocol;
3425 IInternetPriority *priority;
3426 IInternetSession *session;
3427 IWinInetHttpInfo *http_info;
3428 IWinInetInfo *inet_info;
3429 LONG p;
3430 BYTE buf[1000];
3431 DWORD read;
3432 HRESULT hres;
3434 static const WCHAR test_url[] =
3435 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
3436 static const WCHAR wsz_test[] = {'t','e','s','t',0};
3438 trace("Testing CreateBinding...\n");
3439 init_test(BIND_TEST, TEST_BINDING);
3441 hres = pCoInternetGetSession(0, &session, 0);
3442 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3444 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
3445 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3447 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3448 binding_protocol = protocol;
3449 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3450 ok(protocol != NULL, "protocol == NULL\n");
3452 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3453 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3455 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3456 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
3458 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
3459 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3460 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
3461 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3462 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3463 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3465 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
3466 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
3468 p = 0xdeadbeef;
3469 hres = IInternetPriority_GetPriority(priority, &p);
3470 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3471 ok(!p, "p=%d\n", p);
3473 ex_priority = 100;
3474 hres = IInternetPriority_SetPriority(priority, 100);
3475 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3477 p = 0xdeadbeef;
3478 hres = IInternetPriority_GetPriority(priority, &p);
3479 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3480 ok(p == 100, "p=%d\n", p);
3482 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3483 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3485 SET_EXPECT(QueryService_InternetProtocol);
3486 SET_EXPECT(CreateInstance);
3487 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3488 SET_EXPECT(SetPriority);
3489 SET_EXPECT(Start);
3491 expect_hrResult = S_OK;
3492 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3493 ok(hres == S_OK, "Start failed: %08x\n", hres);
3495 CHECK_CALLED(QueryService_InternetProtocol);
3496 CHECK_CALLED(CreateInstance);
3497 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3498 CHECK_CALLED(SetPriority);
3499 CHECK_CALLED(Start);
3501 SET_EXPECT(QueryInterface_IWinInetInfo);
3502 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3503 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3504 CHECK_CALLED(QueryInterface_IWinInetInfo);
3506 SET_EXPECT(QueryInterface_IWinInetInfo);
3507 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3508 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3509 CHECK_CALLED(QueryInterface_IWinInetInfo);
3511 SET_EXPECT(QueryInterface_IWinInetHttpInfo);
3512 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
3513 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3514 CHECK_CALLED(QueryInterface_IWinInetHttpInfo);
3516 SET_EXPECT(Read);
3517 read = 0xdeadbeef;
3518 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3519 ok(hres == S_OK, "Read failed: %08x\n", hres);
3520 ok(read == 100, "read = %d\n", read);
3521 CHECK_CALLED(Read);
3523 SET_EXPECT(Read);
3524 read = 0xdeadbeef;
3525 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3526 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3527 ok(!read, "read = %d\n", read);
3528 CHECK_CALLED(Read);
3530 p = 0xdeadbeef;
3531 hres = IInternetPriority_GetPriority(priority, &p);
3532 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3533 ok(p == 100, "p=%d\n", p);
3535 hres = IInternetPriority_SetPriority(priority, 101);
3536 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3538 SET_EXPECT(Terminate);
3539 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
3540 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3541 CHECK_CALLED(Terminate);
3543 SET_EXPECT(Continue);
3544 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
3545 ok(hres == S_OK, "Switch failed: %08x\n", hres);
3546 CHECK_CALLED(Continue);
3548 hres = IInternetProtocolSink_ReportProgress(binding_sink,
3549 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
3550 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
3552 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
3553 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
3555 hres = IInternetProtocolSink_ReportData(binding_sink, 0, 0, 0);
3556 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
3558 IInternetProtocolSink_Release(binding_sink);
3559 IInternetPriority_Release(priority);
3560 IInternetBindInfo_Release(prot_bind_info);
3561 IInternetProtocol_Release(protocol);
3563 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3564 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3565 ok(protocol != NULL, "protocol == NULL\n");
3567 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3568 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3570 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
3571 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3573 IInternetProtocol_Release(protocol);
3575 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, wsz_test);
3576 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3578 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3579 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3580 ok(protocol != NULL, "protocol == NULL\n");
3582 SET_EXPECT(QueryService_InternetProtocol);
3583 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3584 ok(hres == MK_E_SYNTAX, "Start failed: %08x, expected MK_E_SYNTAX\n", hres);
3585 CHECK_CALLED(QueryService_InternetProtocol);
3587 IInternetProtocol_Release(protocol);
3589 IInternetSession_Release(session);
3592 static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
3594 IInternetProtocolEx *protocolex = NULL;
3595 IInternetProtocol *protocol;
3596 IInternetSession *session;
3597 IUri *uri = NULL;
3598 ULONG ref;
3599 HRESULT hres;
3601 pi = grf_pi;
3603 init_test(prot, test_flags|TEST_BINDING);
3605 hres = pCoInternetGetSession(0, &session, 0);
3606 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3608 if(test_flags & TEST_EMULATEPROT) {
3609 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
3610 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3613 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
3614 binding_protocol = protocol;
3615 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3616 ok(protocol != NULL, "protocol == NULL\n");
3618 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3619 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3621 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3622 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
3624 if(test_flags & TEST_USEIURI) {
3625 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3626 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3628 hres = pCreateUri(binding_urls[prot], Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
3629 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3632 ex_priority = 0;
3633 SET_EXPECT(QueryService_InternetProtocol);
3634 SET_EXPECT(CreateInstance);
3635 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3636 SET_EXPECT(SetPriority);
3637 if(impl_protex)
3638 SET_EXPECT(StartEx);
3639 else
3640 SET_EXPECT(Start);
3642 expect_hrResult = S_OK;
3644 if(protocolex) {
3645 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, pi, 0);
3646 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
3647 }else {
3648 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0);
3649 ok(hres == S_OK, "Start failed: %08x\n", hres);
3652 CHECK_CALLED(QueryService_InternetProtocol);
3653 CHECK_CALLED(CreateInstance);
3654 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3655 CLEAR_CALLED(SetPriority); /* IE11 does not call it. */
3656 if(impl_protex)
3657 CHECK_CALLED(StartEx);
3658 else
3659 CHECK_CALLED(Start);
3661 if(protocolex)
3662 IInternetProtocolEx_Release(protocolex);
3663 if(uri)
3664 IUri_Release(uri);
3666 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
3667 while(prot_state < 4) {
3668 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3669 if(mimefilter_test && filtered_protocol) {
3670 SET_EXPECT(Continue);
3671 IInternetProtocol_Continue(filtered_protocol, pdata);
3672 CHECK_CALLED(Continue);
3673 }else {
3674 SET_EXPECT(Continue);
3675 IInternetProtocol_Continue(protocol, pdata);
3676 CHECK_CALLED(Continue);
3678 if(test_abort && prot_state == 2) {
3679 SET_EXPECT(Abort);
3680 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3681 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3682 CHECK_CALLED(Abort);
3684 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3685 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3686 SetEvent(event_complete2);
3687 break;
3689 SetEvent(event_complete2);
3691 if(direct_read)
3692 CHECK_CALLED(ReportData); /* Set in ReportResult */
3693 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3694 }else {
3695 if(mimefilter_test)
3696 SET_EXPECT(MimeFilter_LockRequest);
3697 else
3698 SET_EXPECT(LockRequest);
3699 hres = IInternetProtocol_LockRequest(protocol, 0);
3700 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3701 if(mimefilter_test)
3702 CHECK_CALLED(MimeFilter_LockRequest);
3703 else
3704 CHECK_CALLED(LockRequest);
3706 if(mimefilter_test)
3707 SET_EXPECT(MimeFilter_UnlockRequest);
3708 else
3709 SET_EXPECT(UnlockRequest);
3710 hres = IInternetProtocol_UnlockRequest(protocol);
3711 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3712 if(mimefilter_test)
3713 CHECK_CALLED(MimeFilter_UnlockRequest);
3714 else
3715 CHECK_CALLED(UnlockRequest);
3718 if(mimefilter_test)
3719 SET_EXPECT(MimeFilter_Terminate);
3720 else
3721 SET_EXPECT(Terminate);
3722 hres = IInternetProtocol_Terminate(protocol, 0);
3723 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3724 if(mimefilter_test)
3725 CLEAR_CALLED(MimeFilter_Terminate);
3726 else
3727 CHECK_CALLED(Terminate);
3729 if(filtered_protocol)
3730 IInternetProtocol_Release(filtered_protocol);
3731 IInternetBindInfo_Release(prot_bind_info);
3732 IInternetProtocolSink_Release(binding_sink);
3733 ref = IInternetProtocol_Release(protocol);
3734 ok(!ref, "ref=%u, expected 0\n", ref);
3736 if(test_flags & TEST_EMULATEPROT) {
3737 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]);
3738 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3741 IInternetSession_Release(session);
3744 START_TEST(protocol)
3746 HMODULE hurlmon;
3748 hurlmon = GetModuleHandleA("urlmon.dll");
3749 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
3750 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
3751 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3753 if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3754 win_skip("Various needed functions not present, too old IE\n");
3755 return;
3758 if(!pCreateUri)
3759 win_skip("CreateUri not supported\n");
3761 OleInitialize(NULL);
3763 event_complete = CreateEventW(NULL, FALSE, FALSE, NULL);
3764 event_complete2 = CreateEventW(NULL, FALSE, FALSE, NULL);
3765 event_continue = CreateEventW(NULL, FALSE, FALSE, NULL);
3766 event_continue_done = CreateEventW(NULL, FALSE, FALSE, NULL);
3767 thread_id = GetCurrentThreadId();
3769 test_file_protocol();
3770 test_http_protocol();
3771 if(pCreateUri)
3772 test_https_protocol();
3773 else
3774 win_skip("Skipping https tests on too old platform\n");
3775 test_ftp_protocol();
3776 test_gopher_protocol();
3777 test_mk_protocol();
3778 test_CreateBinding();
3780 bindf &= ~BINDF_FROMURLMON;
3781 trace("Testing file binding (mime verification, emulate prot)...\n");
3782 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3783 trace("Testing http binding (mime verification, emulate prot)...\n");
3784 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3785 trace("Testing its binding (mime verification, emulate prot)...\n");
3786 test_binding(ITS_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3787 trace("Testing http binding (mime verification, emulate prot, short read, direct read)...\n");
3788 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_SHORT_READ|TEST_DIRECT_READ);
3789 trace("Testing file binding (mime verification, emulate prot, mime filter)...\n");
3790 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3791 trace("Testing http binding (mime verification, emulate prot, mime filter)...\n");
3792 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3793 trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n");
3794 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME);
3795 trace("Testing http binding (mime verification, emulate prot, direct read)...\n");
3796 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
3797 trace("Testing http binding (mime verification, emulate prot, abort)...\n");
3798 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
3799 if(pCreateUri) {
3800 trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
3801 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);
3802 trace("Testing file binding (use IUri, impl StartEx, mime verification, emulate prot)...\n");
3803 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI|TEST_IMPLPROTEX);
3804 trace("Testing file binding (impl StartEx, mime verification, emulate prot)...\n");
3805 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_IMPLPROTEX);
3808 CloseHandle(event_complete);
3809 CloseHandle(event_complete2);
3810 CloseHandle(event_continue);
3811 CloseHandle(event_continue_done);
3813 OleUninitialize();