urlmon/tests: Use common wine_dbgstr_guid implementation from test.h.
[wine.git] / dlls / urlmon / tests / protocol.c
blob33585066c3c9a805a42b96b8d29969c7b3c704be
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(QueryService_HttpNegotiate);
94 DEFINE_EXPECT(QueryService_InternetProtocol);
95 DEFINE_EXPECT(QueryService_HttpSecurity);
96 DEFINE_EXPECT(QueryInterface_IWinInetInfo);
97 DEFINE_EXPECT(QueryInterface_IWinInetHttpInfo);
98 DEFINE_EXPECT(BeginningTransaction);
99 DEFINE_EXPECT(GetRootSecurityId);
100 DEFINE_EXPECT(OnResponse);
101 DEFINE_EXPECT(Switch);
102 DEFINE_EXPECT(Continue);
103 DEFINE_EXPECT(CreateInstance);
104 DEFINE_EXPECT(Start);
105 DEFINE_EXPECT(StartEx);
106 DEFINE_EXPECT(Terminate);
107 DEFINE_EXPECT(Read);
108 DEFINE_EXPECT(Read2);
109 DEFINE_EXPECT(SetPriority);
110 DEFINE_EXPECT(LockRequest);
111 DEFINE_EXPECT(UnlockRequest);
112 DEFINE_EXPECT(Abort);
113 DEFINE_EXPECT(MimeFilter_CreateInstance);
114 DEFINE_EXPECT(MimeFilter_Start);
115 DEFINE_EXPECT(MimeFilter_ReportData);
116 DEFINE_EXPECT(MimeFilter_ReportResult);
117 DEFINE_EXPECT(MimeFilter_Terminate);
118 DEFINE_EXPECT(MimeFilter_LockRequest);
119 DEFINE_EXPECT(MimeFilter_UnlockRequest);
120 DEFINE_EXPECT(MimeFilter_Read);
121 DEFINE_EXPECT(MimeFilter_Switch);
122 DEFINE_EXPECT(MimeFilter_Continue);
123 DEFINE_EXPECT(Stream_Seek);
124 DEFINE_EXPECT(Stream_Read);
126 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
127 static const WCHAR index_url[] =
128 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
130 static const WCHAR acc_mimeW[] = {'*','/','*',0};
131 static const WCHAR user_agentW[] = {'W','i','n','e',0};
132 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
133 static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
134 static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
135 static const WCHAR emptyW[] = {0};
136 static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
137 static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0};
139 static HRESULT expect_hrResult;
140 static LPCWSTR file_name, http_url, expect_wsz;
141 static IInternetProtocol *async_protocol = NULL;
142 static BOOL first_data_notif, http_is_first, test_redirect;
143 static int prot_state, read_report_data, post_stream_read;
144 static DWORD bindf, ex_priority , pi;
145 static IInternetProtocol *binding_protocol, *filtered_protocol;
146 static IInternetBindInfo *prot_bind_info;
147 static IInternetProtocolSink *binding_sink, *filtered_sink;
148 static void *expect_pv;
149 static HANDLE event_complete, event_complete2, event_continue, event_continue_done;
150 static BOOL binding_test;
151 static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
152 static DWORD prot_read, filter_state, http_post_test, thread_id;
153 static BOOL security_problem, test_async_req, impl_protex;
154 static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort;
155 static BOOL empty_file, no_mime, bind_from_cache;
157 enum {
158 STATE_CONNECTING,
159 STATE_SENDINGREQUEST,
160 STATE_STARTDOWNLOADING,
161 STATE_DOWNLOADING
162 } state;
164 static enum {
165 FILE_TEST,
166 HTTP_TEST,
167 HTTPS_TEST,
168 FTP_TEST,
169 MK_TEST,
170 ITS_TEST,
171 BIND_TEST
172 } tested_protocol;
174 static const WCHAR protocol_names[][10] = {
175 {'f','i','l','e',0},
176 {'h','t','t','p',0},
177 {'h','t','t','p','s',0},
178 {'f','t','p',0},
179 {'m','k',0},
180 {'i','t','s',0},
181 {'t','e','s','t',0}
184 static const WCHAR binding_urls[][130] = {
185 {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
186 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
187 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0},
188 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
189 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
190 {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
191 '/','p','u','b','/','o','t','h','e','r',
192 '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
193 {'m','k',':','t','e','s','t',0},
194 {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0},
195 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
198 static const CHAR post_data[] = "mode=Test";
200 static int strcmp_wa(LPCWSTR strw, const char *stra)
202 CHAR buf[512];
203 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
204 return lstrcmpA(stra, buf);
207 static const char *w2a(LPCWSTR str)
209 static char buf[INTERNET_MAX_URL_LENGTH];
210 WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
211 return buf;
214 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
216 if(IsEqualGUID(&IID_IUnknown, riid)
217 || IsEqualGUID(&IID_IHttpSecurity, riid)) {
218 *ppv = iface;
219 return S_OK;
222 ok(0, "unexpected call\n");
223 return E_NOINTERFACE;
226 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
228 return 2;
231 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
233 return 1;
236 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
238 trace("HttpSecurity_GetWindow\n");
240 return S_FALSE;
243 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
245 trace("Security problem: %u\n", dwProblem);
246 ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED, "Expected ERROR_INTERNET_SEC_CERT_REV_FAILED got %u\n", dwProblem);
248 /* Only retry once */
249 if (security_problem)
250 return E_ABORT;
252 security_problem = TRUE;
253 SET_EXPECT(BeginningTransaction);
255 return RPC_E_RETRY;
258 static IHttpSecurityVtbl HttpSecurityVtbl = {
259 HttpSecurity_QueryInterface,
260 HttpSecurity_AddRef,
261 HttpSecurity_Release,
262 HttpSecurity_GetWindow,
263 HttpSecurity_OnSecurityProblem
266 static IHttpSecurity http_security = { &HttpSecurityVtbl };
268 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
270 if(IsEqualGUID(&IID_IUnknown, riid)
271 || IsEqualGUID(&IID_IHttpNegotiate, riid)
272 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
273 *ppv = iface;
274 return S_OK;
277 ok(0, "unexpected call\n");
278 return E_NOINTERFACE;
281 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
283 return 2;
286 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
288 return 1;
291 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
292 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
294 LPWSTR addl_headers;
296 static const WCHAR wszHeaders[] =
297 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
298 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
299 'd','e','d','\r','\n',0};
301 CHECK_EXPECT(BeginningTransaction);
303 if(binding_test)
304 ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
305 else
306 ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
307 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
308 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
309 if(pszAdditionalHeaders)
311 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
312 if (http_post_test)
314 addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
315 memcpy(addl_headers, wszHeaders, sizeof(wszHeaders));
316 *pszAdditionalHeaders = addl_headers;
320 return S_OK;
323 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
324 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
326 CHECK_EXPECT(OnResponse);
328 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
329 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
330 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
331 ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
333 return S_OK;
336 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
337 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
339 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
341 CHECK_EXPECT(GetRootSecurityId);
343 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
344 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
345 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
347 if(pcbSecurityId) {
348 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
349 *pcbSecurityId = sizeof(sec_id);
352 if(pbSecurityId)
353 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
355 return E_FAIL;
358 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
359 HttpNegotiate_QueryInterface,
360 HttpNegotiate_AddRef,
361 HttpNegotiate_Release,
362 HttpNegotiate_BeginningTransaction,
363 HttpNegotiate_OnResponse,
364 HttpNegotiate_GetRootSecurityId
367 static IHttpNegotiate2 http_negotiate = { &HttpNegotiateVtbl };
369 static HRESULT QueryInterface(REFIID,void**);
371 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
373 return QueryInterface(riid, ppv);
376 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
378 return 2;
381 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
383 return 1;
386 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
387 REFIID riid, void **ppv)
389 if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
390 CHECK_EXPECT2(QueryService_HttpNegotiate);
391 return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
394 if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
395 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
396 CHECK_EXPECT(QueryService_InternetProtocol);
397 return E_NOINTERFACE;
400 if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
401 ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
402 CHECK_EXPECT(QueryService_HttpSecurity);
403 return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
406 if(IsEqualGUID(&IID_IGetBindHandle, guidService)) {
407 trace("QueryService(IID_IGetBindHandle)\n");
408 *ppv = NULL;
409 return E_NOINTERFACE;
412 if(IsEqualGUID(&IID_IWindowForBindingUI, guidService)) {
413 trace("QueryService(IID_IWindowForBindingUI)\n");
414 *ppv = NULL;
415 return E_NOINTERFACE;
418 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
419 return E_FAIL;
422 static const IServiceProviderVtbl ServiceProviderVtbl = {
423 ServiceProvider_QueryInterface,
424 ServiceProvider_AddRef,
425 ServiceProvider_Release,
426 ServiceProvider_QueryService
429 static IServiceProvider service_provider = { &ServiceProviderVtbl };
431 static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
433 ok(0, "unexpected call\n");
434 return E_NOINTERFACE;
437 static ULONG WINAPI Stream_AddRef(IStream *iface)
439 return 2;
442 static ULONG WINAPI Stream_Release(IStream *iface)
444 return 1;
447 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
448 ULONG cb, ULONG *pcbRead)
450 CHECK_EXPECT2(Stream_Read);
452 ok(GetCurrentThreadId() != thread_id, "wrong thread %d\n", GetCurrentThreadId());
454 ok(pv != NULL, "pv == NULL\n");
455 ok(cb == 0x20000 || broken(cb == 0x2000), "cb = %d\n", cb);
456 ok(pcbRead != NULL, "pcbRead == NULL\n");
458 if(post_stream_read) {
459 *pcbRead = 0;
460 return S_FALSE;
463 memcpy(pv, post_data, sizeof(post_data)-1);
464 post_stream_read += *pcbRead = sizeof(post_data)-1;
465 return S_OK;
468 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
469 ULONG cb, ULONG *pcbWritten)
471 ok(0, "unexpected call\n");
472 return E_NOTIMPL;
475 static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
476 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
478 CHECK_EXPECT(Stream_Seek);
480 ok(!dlibMove.QuadPart, "dlibMove != 0\n");
481 ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
482 ok(!plibNewPosition, "plibNewPosition == NULL\n");
484 return S_OK;
487 static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
489 ok(0, "unexpected call\n");
490 return E_NOTIMPL;
493 static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm,
494 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
496 ok(0, "unexpected call\n");
497 return E_NOTIMPL;
500 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
502 ok(0, "unexpected call\n");
503 return E_NOTIMPL;
506 static HRESULT WINAPI Stream_Revert(IStream *iface)
508 ok(0, "unexpected call\n");
509 return E_NOTIMPL;
512 static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
513 ULARGE_INTEGER cb, DWORD dwLockType)
515 ok(0, "unexpected call\n");
516 return E_NOTIMPL;
519 static HRESULT WINAPI Stream_UnlockRegion(IStream *iface,
520 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
522 ok(0, "unexpected call\n");
523 return E_NOTIMPL;
526 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
527 DWORD dwStatFlag)
529 ok(0, "unexpected call\n");
530 return E_NOTIMPL;
533 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
535 ok(0, "unexpected call\n");
536 return E_NOTIMPL;
539 static const IStreamVtbl StreamVtbl = {
540 Stream_QueryInterface,
541 Stream_AddRef,
542 Stream_Release,
543 Stream_Read,
544 Stream_Write,
545 Stream_Seek,
546 Stream_SetSize,
547 Stream_CopyTo,
548 Stream_Commit,
549 Stream_Revert,
550 Stream_LockRegion,
551 Stream_UnlockRegion,
552 Stream_Stat,
553 Stream_Clone
556 static IStream Stream = { &StreamVtbl };
558 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
560 return QueryInterface(riid, ppv);
563 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
565 return 2;
568 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
570 return 1;
573 static void call_continue(PROTOCOLDATA *protocol_data)
575 HRESULT hres;
577 if(state == STATE_CONNECTING) {
578 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
579 if (http_is_first){
580 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
581 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
583 CLEAR_CALLED(ReportProgress_CONNECTING);
585 if(tested_protocol == FTP_TEST)
586 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
587 else if (tested_protocol != HTTPS_TEST)
588 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
589 if(test_redirect)
590 CHECK_CALLED(ReportProgress_REDIRECTING);
591 state = test_async_req ? STATE_SENDINGREQUEST : STATE_STARTDOWNLOADING;
594 switch(state) {
595 case STATE_SENDINGREQUEST:
596 SET_EXPECT(Stream_Read);
597 SET_EXPECT(ReportProgress_SENDINGREQUEST);
598 break;
599 case STATE_STARTDOWNLOADING:
600 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
601 SET_EXPECT(OnResponse);
602 if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file)
603 SET_EXPECT(ReportProgress_ACCEPTRANGES);
604 SET_EXPECT(ReportProgress_ENCODING);
605 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
606 if(bindf & BINDF_NEEDFILE)
607 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
609 default:
610 break;
613 if(state != STATE_SENDINGREQUEST)
614 SET_EXPECT(ReportData);
615 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
616 ok(hres == S_OK, "Continue failed: %08x\n", hres);
617 if(tested_protocol == FTP_TEST || security_problem)
618 CLEAR_CALLED(ReportData);
619 else if(state != STATE_SENDINGREQUEST)
620 CHECK_CALLED(ReportData);
622 switch(state) {
623 case STATE_SENDINGREQUEST:
624 CHECK_CALLED(Stream_Read);
625 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
626 state = STATE_STARTDOWNLOADING;
627 break;
628 case STATE_STARTDOWNLOADING:
629 if (! security_problem)
631 state = STATE_DOWNLOADING;
632 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
633 CHECK_CALLED(OnResponse);
634 if(tested_protocol == HTTPS_TEST || empty_file)
635 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
636 else if(test_redirect || test_abort)
637 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
638 CLEAR_CALLED(ReportProgress_ENCODING);
639 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
640 if(bindf & BINDF_NEEDFILE)
641 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
644 else
646 security_problem = FALSE;
647 SET_EXPECT(ReportProgress_CONNECTING);
649 default:
650 break;
654 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
656 if(tested_protocol == FTP_TEST)
657 CHECK_EXPECT2(Switch);
658 else
659 CHECK_EXPECT(Switch);
661 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
662 if(binding_test) {
663 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
664 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
665 pProtocolData->grfFlags, protocoldata.grfFlags );
666 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
667 pProtocolData->dwState, protocoldata.dwState );
668 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
669 pProtocolData->pData, protocoldata.pData );
670 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
671 pProtocolData->cbData, protocoldata.cbData );
674 pdata = pProtocolData;
676 if(binding_test) {
677 SetEvent(event_complete);
678 ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
679 return S_OK;
680 }if(direct_read) {
681 continue_protdata = *pProtocolData;
682 SetEvent(event_continue);
683 ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
684 }else {
685 call_continue(pProtocolData);
686 SetEvent(event_complete);
689 return S_OK;
692 static const char *status_names[] =
694 "0",
695 "FINDINGRESOURCE",
696 "CONNECTING",
697 "REDIRECTING",
698 "BEGINDOWNLOADDATA",
699 "DOWNLOADINGDATA",
700 "ENDDOWNLOADDATA",
701 "BEGINDOWNLOADCOMPONENTS",
702 "INSTALLINGCOMPONENTS",
703 "ENDDOWNLOADCOMPONENTS",
704 "USINGCACHEDCOPY",
705 "SENDINGREQUEST",
706 "CLASSIDAVAILABLE",
707 "MIMETYPEAVAILABLE",
708 "CACHEFILENAMEAVAILABLE",
709 "BEGINSYNCOPERATION",
710 "ENDSYNCOPERATION",
711 "BEGINUPLOADDATA",
712 "UPLOADINGDATA",
713 "ENDUPLOADINGDATA",
714 "PROTOCOLCLASSID",
715 "ENCODING",
716 "VERIFIEDMIMETYPEAVAILABLE",
717 "CLASSINSTALLLOCATION",
718 "DECODING",
719 "LOADINGMIMEHANDLER",
720 "CONTENTDISPOSITIONATTACH",
721 "FILTERREPORTMIMETYPE",
722 "CLSIDCANINSTANTIATE",
723 "IUNKNOWNAVAILABLE",
724 "DIRECTBIND",
725 "RAWMIMETYPE",
726 "PROXYDETECTING",
727 "ACCEPTRANGES",
728 "COOKIE_SENT",
729 "COMPACT_POLICY_RECEIVED",
730 "COOKIE_SUPPRESSED",
731 "COOKIE_STATE_UNKNOWN",
732 "COOKIE_STATE_ACCEPT",
733 "COOKIE_STATE_REJECT",
734 "COOKIE_STATE_PROMPT",
735 "COOKIE_STATE_LEASH",
736 "COOKIE_STATE_DOWNGRADE",
737 "POLICY_HREF",
738 "P3P_HEADER",
739 "SESSION_COOKIE_RECEIVED",
740 "PERSISTENT_COOKIE_RECEIVED",
741 "SESSION_COOKIES_ALLOWED",
742 "CACHECONTROL",
743 "CONTENTDISPOSITIONFILENAME",
744 "MIMETEXTPLAINMISMATCH",
745 "PUBLISHERAVAILABLE",
746 "DISPLAYNAMEAVAILABLE"
749 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
750 LPCWSTR szStatusText)
752 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
753 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
754 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
756 if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0]))
757 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
758 else
759 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
761 switch(ulStatusCode) {
762 case BINDSTATUS_MIMETYPEAVAILABLE:
763 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
764 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
765 if(!short_read || !direct_read)
766 CHECK_CALLED(Read); /* set in Continue */
767 else if(short_read)
768 CHECK_CALLED(Read2); /* set in Read */
770 ok(szStatusText != NULL, "szStatusText == NULL\n");
771 if(szStatusText) {
772 if(tested_protocol == BIND_TEST)
773 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
774 else if (http_post_test)
775 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
776 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
777 "szStatusText != text/plain\n");
778 else if(empty_file)
779 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
780 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
781 && tested_protocol==HTTP_TEST && !short_read)
782 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
783 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
784 "szStatusText != image/gif\n");
785 else if(!mimefilter_test)
786 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
787 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
788 "szStatusText != text/html\n");
790 break;
791 case BINDSTATUS_DIRECTBIND:
792 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
793 ok(szStatusText == NULL, "szStatusText != NULL\n");
794 break;
795 case BINDSTATUS_RAWMIMETYPE:
796 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
797 ok(szStatusText != NULL, "szStatusText == NULL\n");
798 if(szStatusText)
799 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
800 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
801 "szStatusText != text/html\n");
802 break;
803 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
804 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
805 ok(szStatusText != NULL, "szStatusText == NULL\n");
806 if(szStatusText) {
807 if(binding_test)
808 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
809 else if(tested_protocol == FILE_TEST)
810 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
811 else
812 ok(szStatusText != NULL, "szStatusText == NULL\n");
814 break;
815 case BINDSTATUS_FINDINGRESOURCE:
816 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
817 ok(szStatusText != NULL, "szStatusText == NULL\n");
818 break;
819 case BINDSTATUS_CONNECTING:
820 CHECK_EXPECT2(ReportProgress_CONNECTING);
821 ok(szStatusText != NULL, "szStatusText == NULL\n");
822 break;
823 case BINDSTATUS_SENDINGREQUEST:
824 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
825 if(tested_protocol == FILE_TEST || tested_protocol == ITS_TEST) {
826 ok(szStatusText != NULL, "szStatusText == NULL\n");
827 if(szStatusText)
828 ok(!*szStatusText, "wrong szStatusText\n");
830 break;
831 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
832 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
833 ok(szStatusText != NULL, "szStatusText == NULL\n");
834 if(szStatusText)
835 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
836 break;
837 case BINDSTATUS_PROTOCOLCLASSID:
838 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
839 ok(szStatusText != NULL, "szStatusText == NULL\n");
840 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
841 break;
842 case BINDSTATUS_COOKIE_SENT:
843 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
844 ok(szStatusText == NULL, "szStatusText != NULL\n");
845 break;
846 case BINDSTATUS_REDIRECTING:
847 CHECK_EXPECT(ReportProgress_REDIRECTING);
848 if(test_redirect)
849 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
850 else
851 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
852 break;
853 case BINDSTATUS_ENCODING:
854 CHECK_EXPECT(ReportProgress_ENCODING);
855 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
856 break;
857 case BINDSTATUS_ACCEPTRANGES:
858 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
859 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
860 break;
861 case BINDSTATUS_PROXYDETECTING:
862 if(!called_ReportProgress_PROXYDETECTING)
863 SET_EXPECT(ReportProgress_CONNECTING);
864 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
865 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
866 break;
867 case BINDSTATUS_LOADINGMIMEHANDLER:
868 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
869 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
870 break;
871 case BINDSTATUS_DECODING:
872 CHECK_EXPECT(ReportProgress_DECODING);
873 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
874 break;
875 case BINDSTATUS_RESERVED_7:
876 trace("BINDSTATUS_RESERVED_7\n");
877 break;
878 default:
879 ok(0, "Unexpected status %d (%d)\n", ulStatusCode, ulStatusCode-BINDSTATUS_LAST);
882 return S_OK;
885 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
886 ULONG ulProgress, ULONG ulProgressMax)
888 HRESULT hres;
890 static int rec_depth;
891 rec_depth++;
893 if(!mimefilter_test && (tested_protocol == FILE_TEST || tested_protocol == ITS_TEST)) {
894 CHECK_EXPECT2(ReportData);
896 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
897 ulProgress, ulProgressMax);
898 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
899 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
900 if(tested_protocol == FILE_TEST)
901 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
902 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
903 "grcfBSCF = %08x\n", grfBSCF);
904 else
905 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
906 }else if(bind_from_cache) {
907 CHECK_EXPECT(ReportData);
909 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
910 ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
911 ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
912 }else if(direct_read) {
913 BYTE buf[14096];
914 ULONG read;
916 if(!read_report_data && rec_depth == 1) {
917 BOOL reported_all_data = called_ReportData2;
919 CHECK_EXPECT2(ReportData);
921 if(short_read) {
922 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
923 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
924 "grcfBSCF = %08x\n", grfBSCF);
925 CHECK_CALLED(Read); /* Set in Continue */
926 first_data_notif = FALSE;
927 }else if(first_data_notif) {
928 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
929 first_data_notif = FALSE;
930 }else if(reported_all_data) {
931 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
932 "grcfBSCF = %08x\n", grfBSCF);
933 }else if(!direct_read) {
934 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
937 do {
938 read = 0;
939 if(emulate_prot)
940 SET_EXPECT(Read);
941 else
942 SET_EXPECT(ReportData2);
943 SET_EXPECT(ReportResult);
944 if(!emulate_prot)
945 SET_EXPECT(Switch);
946 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
947 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
948 if(hres == S_OK)
949 ok(read, "read == 0\n");
950 if(reported_all_data)
951 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
952 if(!emulate_prot && hres != E_PENDING)
953 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
954 if(emulate_prot)
955 CHECK_CALLED(Read);
956 if(!reported_all_data && called_ReportData2) {
957 if(!emulate_prot)
958 CHECK_CALLED(ReportData2);
959 CHECK_CALLED(ReportResult);
960 reported_all_data = TRUE;
961 }else {
962 if(!emulate_prot)
963 CHECK_NOT_CALLED(ReportData2);
964 CHECK_NOT_CALLED(ReportResult);
966 }while(hres == S_OK);
967 if(hres == S_FALSE)
968 wait_for_switch = FALSE;
969 }else {
970 CHECK_EXPECT(ReportData2);
972 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
974 read = 0xdeadbeef;
975 if(emulate_prot)
976 SET_EXPECT(Read2);
977 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
978 if(emulate_prot)
979 CHECK_CALLED(Read2);
980 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
981 ok(!read, "read = %d\n", read);
983 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST
984 || tested_protocol == FTP_TEST)) {
985 if(empty_file)
986 CHECK_EXPECT2(ReportData);
987 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
988 CHECK_EXPECT(ReportData);
989 else if (http_post_test)
990 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
992 if(empty_file) {
993 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
994 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
995 }else {
996 ok(ulProgress, "ulProgress == 0\n");
999 if(empty_file) {
1000 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
1001 "grcfBSCF = %08x\n", grfBSCF);
1002 first_data_notif = FALSE;
1003 }else if(first_data_notif) {
1004 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1005 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1006 "grcfBSCF = %08x\n", grfBSCF);
1007 first_data_notif = FALSE;
1008 } else {
1009 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1010 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1011 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1012 "grcfBSCF = %08x\n", grfBSCF);
1015 if(!(bindf & BINDF_FROMURLMON) &&
1016 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1017 if(state == STATE_CONNECTING) {
1018 state = STATE_DOWNLOADING;
1019 if(http_is_first) {
1020 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1021 CHECK_CALLED(ReportProgress_CONNECTING);
1023 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1024 CHECK_CALLED(OnResponse);
1025 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1027 SetEvent(event_complete);
1029 }else if(!read_report_data) {
1030 BYTE buf[1000];
1031 ULONG read;
1032 HRESULT hres;
1034 CHECK_EXPECT(ReportData);
1036 if(tested_protocol != BIND_TEST) {
1037 do {
1038 if(mimefilter_test)
1039 SET_EXPECT(MimeFilter_Read);
1040 else if(rec_depth > 1)
1041 SET_EXPECT(Read2);
1042 else
1043 SET_EXPECT(Read);
1044 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1045 if(mimefilter_test)
1046 CHECK_CALLED(MimeFilter_Read);
1047 else if(rec_depth > 1)
1048 CHECK_CALLED(Read2);
1049 else
1050 CHECK_CALLED(Read);
1051 }while(hres == S_OK);
1055 rec_depth--;
1056 return S_OK;
1059 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1060 DWORD dwError, LPCWSTR szResult)
1062 CHECK_EXPECT(ReportResult);
1064 if(tested_protocol == FTP_TEST)
1065 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1066 else
1067 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1068 hrResult, expect_hrResult);
1069 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort)
1070 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1071 else
1072 ok(dwError != ERROR_SUCCESS ||
1073 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1074 "dwError == ERROR_SUCCESS\n");
1075 ok(!szResult, "szResult != NULL\n");
1077 if(direct_read)
1078 SET_EXPECT(ReportData); /* checked after main loop */
1080 return S_OK;
1083 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1084 ProtocolSink_QueryInterface,
1085 ProtocolSink_AddRef,
1086 ProtocolSink_Release,
1087 ProtocolSink_Switch,
1088 ProtocolSink_ReportProgress,
1089 ProtocolSink_ReportData,
1090 ProtocolSink_ReportResult
1093 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
1095 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
1097 ok(0, "unexpected call\n");
1098 return E_NOTIMPL;
1101 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1103 return 2;
1106 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1108 return 1;
1111 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1113 HRESULT hres;
1115 CHECK_EXPECT(MimeFilter_Switch);
1117 SET_EXPECT(Switch);
1118 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1119 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1120 CHECK_CALLED(Switch);
1122 return S_OK;
1125 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1126 LPCWSTR szStatusText)
1128 switch(ulStatusCode) {
1129 case BINDSTATUS_LOADINGMIMEHANDLER:
1131 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1132 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1133 * ProtocolSink_ReportProgress to workaround it.
1135 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1136 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1137 break;
1138 default:
1139 ok(0, "Unexpected status code %d\n", ulStatusCode);
1142 return S_OK;
1145 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1146 ULONG ulProgress, ULONG ulProgressMax)
1148 DWORD read = 0;
1149 BYTE buf[8192];
1150 HRESULT hres;
1151 BOOL report_mime = FALSE;
1153 CHECK_EXPECT(MimeFilter_ReportData);
1155 if(!filter_state && !no_mime) {
1156 SET_EXPECT(Read);
1157 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1158 if(tested_protocol == HTTP_TEST)
1159 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1160 else
1161 ok(hres == S_OK, "Read failed: %08x\n", hres);
1162 CHECK_CALLED(Read);
1164 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1165 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1166 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1167 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1169 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1170 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1171 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1172 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1174 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1177 if(no_mime && prot_read<200) {
1178 SET_EXPECT(Read);
1179 }else if(no_mime && prot_read<300) {
1180 report_mime = TRUE;
1181 SET_EXPECT(Read);
1182 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1183 SET_EXPECT(ReportData);
1184 }else if(!read_report_data) {
1185 SET_EXPECT(ReportData);
1187 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1188 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1189 if(no_mime && prot_read<=200) {
1190 CHECK_CALLED(Read);
1191 }else if(report_mime) {
1192 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1193 CHECK_CALLED(ReportData);
1194 }else if(!read_report_data) {
1195 CHECK_CALLED(ReportData);
1198 if(!filter_state)
1199 filter_state = 1;
1201 return S_OK;
1204 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1205 DWORD dwError, LPCWSTR szResult)
1207 HRESULT hres;
1209 CHECK_EXPECT(MimeFilter_ReportResult);
1211 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1212 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1213 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1215 SET_EXPECT(ReportResult);
1216 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1217 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1218 CHECK_CALLED(ReportResult);
1220 return S_OK;
1223 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1224 MimeProtocolSink_QueryInterface,
1225 MimeProtocolSink_AddRef,
1226 MimeProtocolSink_Release,
1227 MimeProtocolSink_Switch,
1228 MimeProtocolSink_ReportProgress,
1229 MimeProtocolSink_ReportData,
1230 MimeProtocolSink_ReportResult
1233 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1235 static HRESULT QueryInterface(REFIID riid, void **ppv)
1237 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1238 static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1240 *ppv = NULL;
1242 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1243 *ppv = &protocol_sink;
1244 if(IsEqualGUID(&IID_IServiceProvider, riid))
1245 *ppv = &service_provider;
1246 if(IsEqualGUID(&IID_IUriContainer, riid))
1247 return E_NOINTERFACE; /* TODO */
1249 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1250 if(IsEqualGUID(&IID_undocumented, riid))
1251 return E_NOINTERFACE;
1252 /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1253 if(IsEqualGUID(&IID_undocumentedIE10, riid))
1254 return E_NOINTERFACE;
1256 if(*ppv)
1257 return S_OK;
1259 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1260 return E_NOINTERFACE;
1263 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1265 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1266 *ppv = iface;
1267 return S_OK;
1269 return E_NOINTERFACE;
1272 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1274 return 2;
1277 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1279 return 1;
1282 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1284 DWORD cbSize;
1286 CHECK_EXPECT(GetBindInfo);
1288 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1289 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1290 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1292 *grfBINDF = bindf;
1293 if(binding_test)
1294 *grfBINDF |= BINDF_FROMURLMON;
1295 cbSize = pbindinfo->cbSize;
1296 memset(pbindinfo, 0, cbSize);
1297 pbindinfo->cbSize = cbSize;
1299 if(http_post_test)
1301 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1302 pbindinfo->dwBindVerb = BINDVERB_POST;
1303 pbindinfo->stgmedData.tymed = http_post_test;
1305 if(http_post_test == TYMED_HGLOBAL) {
1306 HGLOBAL data;
1308 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1309 data = GlobalAlloc(GPTR, sizeof(post_data));
1310 memcpy(data, post_data, sizeof(post_data));
1311 U(pbindinfo->stgmedData).hGlobal = data;
1312 }else {
1313 IStream *post_stream;
1314 HGLOBAL data;
1315 HRESULT hres;
1317 if(0) {
1318 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1319 data = GlobalAlloc(GPTR, sizeof(post_data));
1320 memcpy(data, post_data, sizeof(post_data));
1321 U(pbindinfo->stgmedData).hGlobal = data;
1323 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1324 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1326 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1328 U(pbindinfo->stgmedData).pstm = &Stream;
1332 return S_OK;
1335 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1336 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1338 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1339 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1341 switch(ulStringType) {
1342 case BINDSTRING_ACCEPT_MIMES:
1343 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1344 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1345 if(pcElFetched) {
1346 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1347 *pcElFetched = 1;
1349 if(ppwzStr) {
1350 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1351 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1353 return S_OK;
1354 case BINDSTRING_USER_AGENT:
1355 CHECK_EXPECT(GetBindString_USER_AGENT);
1356 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1357 if(pcElFetched) {
1358 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1359 *pcElFetched = 1;
1361 if(ppwzStr) {
1362 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1363 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1365 return S_OK;
1366 case BINDSTRING_POST_COOKIE:
1367 CHECK_EXPECT(GetBindString_POST_COOKIE);
1368 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1369 if(pcElFetched)
1370 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1371 return S_OK;
1372 case BINDSTRING_URL: {
1373 DWORD size;
1375 CHECK_EXPECT(GetBindString_URL);
1376 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1377 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1378 *pcElFetched = 1;
1380 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1381 *ppwzStr = CoTaskMemAlloc(size);
1382 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1383 return S_OK;
1385 default:
1386 ok(0, "unexpected call\n");
1389 return E_NOTIMPL;
1392 static IInternetBindInfoVtbl bind_info_vtbl = {
1393 BindInfo_QueryInterface,
1394 BindInfo_AddRef,
1395 BindInfo_Release,
1396 BindInfo_GetBindInfo,
1397 BindInfo_GetBindString
1400 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1402 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1403 REFIID riid, void **ppv)
1405 ok(0, "unexpected call\n");
1406 return E_NOINTERFACE;
1409 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1411 return 2;
1414 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1416 return 1;
1419 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1421 CHECK_EXPECT(SetPriority);
1422 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1423 return S_OK;
1426 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1428 ok(0, "unexpected call\n");
1429 return E_NOTIMPL;
1433 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1434 InternetPriority_QueryInterface,
1435 InternetPriority_AddRef,
1436 InternetPriority_Release,
1437 InternetPriority_SetPriority,
1438 InternetPriority_GetPriority
1441 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1443 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1445 return 2;
1448 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1450 return 1;
1453 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1454 DWORD dwOptions)
1456 HRESULT hres;
1458 CHECK_EXPECT(Abort);
1460 SET_EXPECT(ReportResult);
1461 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1462 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1463 CHECK_CALLED(ReportResult);
1465 return S_OK;
1468 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1470 ok(0, "unexpected call\n");
1471 return E_NOTIMPL;
1474 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1476 ok(0, "unexpected call\n");
1477 return E_NOTIMPL;
1480 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1481 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1483 ok(0, "unexpected call\n");
1484 return E_NOTIMPL;
1487 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1489 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1491 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1492 *ppv = iface;
1493 return S_OK;
1496 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1497 if(impl_protex) {
1498 *ppv = iface;
1499 return S_OK;
1501 *ppv = NULL;
1502 return E_NOINTERFACE;
1505 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1506 *ppv = &InternetPriority;
1507 return S_OK;
1510 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1511 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1512 *ppv = NULL;
1513 return E_NOINTERFACE;
1516 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1517 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1518 *ppv = NULL;
1519 return E_NOINTERFACE;
1522 if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */
1523 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1524 *ppv = NULL;
1525 return E_NOINTERFACE;
1528 static DWORD WINAPI thread_proc(PVOID arg)
1530 HRESULT hres;
1532 memset(&protocoldata, -1, sizeof(protocoldata));
1534 prot_state = 0;
1536 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1537 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1538 BINDSTATUS_FINDINGRESOURCE, hostW);
1539 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1540 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1542 SET_EXPECT(ReportProgress_CONNECTING);
1543 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1544 BINDSTATUS_CONNECTING, winehq_ipW);
1545 CHECK_CALLED(ReportProgress_CONNECTING);
1546 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1548 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1549 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1550 BINDSTATUS_SENDINGREQUEST, NULL);
1551 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1552 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1554 prot_state = 1;
1555 SET_EXPECT(Switch);
1556 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1557 CHECK_CALLED(Switch);
1558 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1560 if(!short_read) {
1561 prot_state = 2;
1562 if(mimefilter_test)
1563 SET_EXPECT(MimeFilter_Switch);
1564 else
1565 SET_EXPECT(Switch);
1566 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1567 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1568 if(mimefilter_test)
1569 CHECK_CALLED(MimeFilter_Switch);
1570 else
1571 CHECK_CALLED(Switch);
1573 if(test_abort) {
1574 SetEvent(event_complete);
1575 return 0;
1578 prot_state = 2;
1579 if(mimefilter_test)
1580 SET_EXPECT(MimeFilter_Switch);
1581 else
1582 SET_EXPECT(Switch);
1583 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1584 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1585 if(mimefilter_test)
1586 CHECK_CALLED(MimeFilter_Switch);
1587 else
1588 CHECK_CALLED(Switch);
1590 prot_state = 3;
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);
1603 SetEvent(event_complete);
1605 return 0;
1608 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1610 BINDINFO bindinfo, exp_bindinfo;
1611 DWORD cbindf = 0;
1612 HRESULT hres;
1614 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1615 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1616 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1617 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1618 ok(!pi, "pi = %x\n", pi);
1620 if(binding_test)
1621 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1623 memset(&bindinfo, 0, sizeof(bindinfo));
1624 bindinfo.cbSize = sizeof(bindinfo);
1625 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1626 SET_EXPECT(GetBindInfo);
1627 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1628 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1629 CHECK_CALLED(GetBindInfo);
1630 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1631 cbindf, (bindf|BINDF_FROMURLMON));
1632 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1633 pReleaseBindInfo(&bindinfo);
1635 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1636 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1637 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1638 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1640 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1641 IServiceProvider *service_provider;
1642 IHttpNegotiate *http_negotiate;
1643 IHttpNegotiate2 *http_negotiate2;
1644 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1645 LPWSTR additional_headers = NULL;
1646 BYTE sec_id[100];
1647 DWORD fetched = 0, size = 100;
1648 DWORD tid;
1650 SET_EXPECT(GetBindString_USER_AGENT);
1651 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1652 &ua, 1, &fetched);
1653 CHECK_CALLED(GetBindString_USER_AGENT);
1654 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1655 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1656 ok(ua != NULL, "ua = %p\n", ua);
1657 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1658 CoTaskMemFree(ua);
1660 fetched = 256;
1661 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1662 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1663 accept_mimes, 256, &fetched);
1664 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1666 ok(hres == S_OK,
1667 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1668 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1669 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1670 CoTaskMemFree(accept_mimes[0]);
1672 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1673 (void**)&service_provider);
1674 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1676 SET_EXPECT(QueryService_HttpNegotiate);
1677 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1678 &IID_IHttpNegotiate, (void**)&http_negotiate);
1679 CHECK_CALLED(QueryService_HttpNegotiate);
1680 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1682 SET_EXPECT(BeginningTransaction);
1683 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1684 NULL, 0, &additional_headers);
1685 CHECK_CALLED(BeginningTransaction);
1686 IHttpNegotiate_Release(http_negotiate);
1687 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1688 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1690 SET_EXPECT(QueryService_HttpNegotiate);
1691 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1692 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1693 CHECK_CALLED(QueryService_HttpNegotiate);
1694 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1696 size = 512;
1697 SET_EXPECT(GetRootSecurityId);
1698 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1699 CHECK_CALLED(GetRootSecurityId);
1700 IHttpNegotiate2_Release(http_negotiate2);
1701 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1702 ok(size == 13, "size=%d\n", size);
1704 IServiceProvider_Release(service_provider);
1706 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1707 return;
1710 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1711 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1712 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1713 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1714 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1716 if(mimefilter_test) {
1717 SET_EXPECT(MimeFilter_CreateInstance);
1718 SET_EXPECT(MimeFilter_Start);
1719 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1721 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1722 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1723 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1724 ok(hres == S_OK,
1725 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1726 if(mimefilter_test) {
1727 CHECK_CALLED(MimeFilter_CreateInstance);
1728 CHECK_CALLED(MimeFilter_Start);
1729 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1730 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1731 }else {
1732 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1735 if(mimefilter_test)
1736 SET_EXPECT(MimeFilter_ReportData);
1737 else
1738 SET_EXPECT(ReportData);
1739 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1740 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1741 13, 13);
1742 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1743 if(mimefilter_test)
1744 CHECK_CALLED(MimeFilter_ReportData);
1745 else
1746 CHECK_CALLED(ReportData);
1748 if(tested_protocol == ITS_TEST) {
1749 SET_EXPECT(ReportData);
1750 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1751 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1752 CHECK_CALLED(ReportData);
1755 if(tested_protocol == BIND_TEST) {
1756 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1757 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1760 if(mimefilter_test)
1761 SET_EXPECT(MimeFilter_ReportResult);
1762 else
1763 SET_EXPECT(ReportResult);
1764 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1765 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1766 if(mimefilter_test)
1767 CHECK_CALLED(MimeFilter_ReportResult);
1768 else
1769 CHECK_CALLED(ReportResult);
1772 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1773 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1774 DWORD grfPI, HANDLE_PTR dwReserved)
1776 CHECK_EXPECT(Start);
1778 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1779 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1780 return S_OK;
1783 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1784 PROTOCOLDATA *pProtocolData)
1786 DWORD bscf = 0, pr;
1787 HRESULT hres;
1789 CHECK_EXPECT(Continue);
1791 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1792 if(!pProtocolData || tested_protocol == BIND_TEST)
1793 return S_OK;
1794 if(binding_test) {
1795 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1796 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1797 pProtocolData->grfFlags, protocoldata.grfFlags );
1798 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1799 pProtocolData->dwState, protocoldata.dwState );
1800 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1801 pProtocolData->pData, protocoldata.pData );
1802 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1803 pProtocolData->cbData, protocoldata.cbData );
1806 switch(prot_state) {
1807 case 1: {
1808 IServiceProvider *service_provider;
1809 IHttpNegotiate *http_negotiate;
1810 static const WCHAR header[] = {'?',0};
1812 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1813 (void**)&service_provider);
1814 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1816 SET_EXPECT(QueryService_HttpNegotiate);
1817 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1818 &IID_IHttpNegotiate, (void**)&http_negotiate);
1819 IServiceProvider_Release(service_provider);
1820 CHECK_CALLED(QueryService_HttpNegotiate);
1821 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1823 SET_EXPECT(OnResponse);
1824 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1825 IHttpNegotiate_Release(http_negotiate);
1826 CHECK_CALLED(OnResponse);
1827 IHttpNegotiate_Release(http_negotiate);
1828 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1830 if(mimefilter_test) {
1831 SET_EXPECT(MimeFilter_CreateInstance);
1832 SET_EXPECT(MimeFilter_Start);
1833 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1834 }else if(!(pi & PI_MIMEVERIFICATION)) {
1835 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1837 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1838 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1839 if(mimefilter_test) {
1840 CHECK_CALLED(MimeFilter_CreateInstance);
1841 CHECK_CALLED(MimeFilter_Start);
1842 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1843 }else if(!(pi & PI_MIMEVERIFICATION)) {
1844 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1846 ok(hres == S_OK,
1847 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1849 bscf |= BSCF_FIRSTDATANOTIFICATION;
1850 break;
1852 case 2:
1853 case 3:
1854 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1855 break;
1858 pr = prot_read;
1859 if(mimefilter_test)
1860 SET_EXPECT(MimeFilter_ReportData);
1861 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1862 if(pr < 200)
1863 SET_EXPECT(Read); /* checked in ReportData for short_read */
1864 if(pr == 200) {
1865 if(!mimefilter_test)
1866 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1867 SET_EXPECT(GetBindInfo);
1868 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1870 if(pr >= 200)
1871 SET_EXPECT(ReportData);
1872 }else {
1873 SET_EXPECT(ReportData);
1876 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1877 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1879 if(mimefilter_test) {
1880 SET_EXPECT(MimeFilter_ReportData);
1881 }else if(pi & PI_MIMEVERIFICATION) {
1882 if(!short_read && pr < 200)
1883 CHECK_CALLED(Read);
1884 if(pr == 200) {
1885 CLEAR_CALLED(GetBindInfo); /* IE9 */
1886 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1888 }else {
1889 CHECK_CALLED(ReportData);
1892 if(prot_state == 3)
1893 prot_state = 4;
1895 return S_OK;
1898 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1900 CHECK_EXPECT(Terminate);
1901 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1902 return S_OK;
1905 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1906 ULONG cb, ULONG *pcbRead)
1908 if(read_report_data)
1909 CHECK_EXPECT2(Read2);
1911 if(mimefilter_test || short_read) {
1912 if(!read_report_data)
1913 CHECK_EXPECT2(Read);
1914 }else if((pi & PI_MIMEVERIFICATION)) {
1915 if(!read_report_data)
1916 CHECK_EXPECT2(Read);
1918 if(prot_read < 300) {
1919 ok(pv != expect_pv, "pv == expect_pv\n");
1920 if(prot_read < 300)
1921 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1922 else
1923 ok(cb == 700, "cb=%d\n", cb);
1924 }else {
1925 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1927 }else {
1928 if(!read_report_data)
1929 CHECK_EXPECT(Read);
1931 ok(pv == expect_pv, "pv != expect_pv\n");
1932 ok(cb == 1000, "cb=%d\n", cb);
1933 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1935 ok(pcbRead != NULL, "pcbRead == NULL\n");
1937 if(prot_state == 3 || (short_read && prot_state != 4)) {
1938 HRESULT hres;
1940 prot_state = 4;
1941 if(short_read) {
1942 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1943 SET_EXPECT(GetBindInfo);
1944 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1946 if(mimefilter_test)
1947 SET_EXPECT(MimeFilter_ReportData);
1948 else if(direct_read)
1949 SET_EXPECT(ReportData2);
1950 read_report_data++;
1951 hres = IInternetProtocolSink_ReportData(binding_sink,
1952 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1953 read_report_data--;
1954 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1955 if(short_read) {
1956 CLEAR_CALLED(GetBindInfo); /* IE9 */
1957 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1959 if(mimefilter_test)
1960 CHECK_CALLED(MimeFilter_ReportData);
1961 else if(direct_read)
1962 CHECK_CALLED(ReportData2);
1964 if(mimefilter_test)
1965 SET_EXPECT(MimeFilter_ReportResult);
1966 else
1967 SET_EXPECT(ReportResult);
1968 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1969 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1970 if(mimefilter_test)
1971 CHECK_CALLED(MimeFilter_ReportResult);
1972 else
1973 CHECK_CALLED(ReportResult);
1975 if(cb > 100)
1976 cb = 100;
1977 memset(pv, 'x', cb);
1978 if(cb>6)
1979 memcpy(pv, "gif87a", 6);
1980 prot_read += *pcbRead = cb;
1981 return S_OK;
1982 }if(prot_state == 4) {
1983 *pcbRead = 0;
1984 return S_FALSE;
1987 if((async_read_pending = !async_read_pending)) {
1988 *pcbRead = 0;
1989 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
1992 if(cb > 100)
1993 cb = 100;
1994 memset(pv, 'x', cb);
1995 if(cb>6)
1996 memcpy(pv, "gif87a", 6);
1997 prot_read += *pcbRead = cb;
1998 return S_OK;
2001 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2003 CHECK_EXPECT(LockRequest);
2004 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2005 return S_OK;
2008 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2010 CHECK_EXPECT(UnlockRequest);
2011 return S_OK;
2014 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2015 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2016 DWORD grfPI, HANDLE *dwReserved)
2018 CHECK_EXPECT(StartEx);
2019 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2020 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2021 return S_OK;
2024 static const IInternetProtocolExVtbl ProtocolVtbl = {
2025 ProtocolEmul_QueryInterface,
2026 Protocol_AddRef,
2027 Protocol_Release,
2028 ProtocolEmul_Start,
2029 ProtocolEmul_Continue,
2030 Protocol_Abort,
2031 ProtocolEmul_Terminate,
2032 Protocol_Suspend,
2033 Protocol_Resume,
2034 ProtocolEmul_Read,
2035 Protocol_Seek,
2036 ProtocolEmul_LockRequest,
2037 ProtocolEmul_UnlockRequest,
2038 ProtocolEmul_StartEx
2041 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2043 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2045 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2046 *ppv = iface;
2047 return S_OK;
2050 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2051 *ppv = &mime_protocol_sink;
2052 return S_OK;
2055 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2056 *ppv = NULL;
2057 return E_NOINTERFACE;
2060 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2061 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2062 DWORD grfPI, HANDLE_PTR dwReserved)
2064 PROTOCOLFILTERDATA *data;
2065 LPOLESTR url_str = NULL;
2066 DWORD fetched = 0;
2067 BINDINFO bindinfo;
2068 DWORD cbindf = 0;
2069 HRESULT hres;
2071 CHECK_EXPECT(MimeFilter_Start);
2073 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2074 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2075 ok(dwReserved, "dwReserved == 0\n");
2076 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2077 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2079 if(binding_test) {
2080 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2081 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2082 }else {
2083 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2084 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2087 data = (void*)dwReserved;
2088 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2089 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2090 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2091 ok(!data->pUnk, "data->pUnk != NULL\n");
2092 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2093 if(binding_test) {
2094 IInternetProtocolSink *prot_sink;
2096 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2097 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2098 IInternetProtocolSink_Release(prot_sink);
2100 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2102 filtered_protocol = data->pProtocol;
2103 IInternetProtocol_AddRef(filtered_protocol);
2104 }else {
2105 IInternetProtocol *prot;
2107 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2108 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2109 IInternetProtocol_Release(prot);
2111 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2114 filtered_sink = pOIProtSink;
2116 SET_EXPECT(ReportProgress_DECODING);
2117 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2118 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2119 CHECK_CALLED(ReportProgress_DECODING);
2121 SET_EXPECT(GetBindInfo);
2122 memset(&bindinfo, 0, sizeof(bindinfo));
2123 bindinfo.cbSize = sizeof(bindinfo);
2124 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2125 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2126 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2127 CHECK_CALLED(GetBindInfo);
2129 SET_EXPECT(GetBindString_URL);
2130 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2131 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2132 ok(fetched == 1, "fetched = %d\n", fetched);
2133 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2134 CoTaskMemFree(url_str);
2135 CHECK_CALLED(GetBindString_URL);
2137 return S_OK;
2140 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2141 PROTOCOLDATA *pProtocolData)
2143 CHECK_EXPECT(MimeFilter_Continue);
2144 return E_NOTIMPL;
2147 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2149 HRESULT hres;
2151 CHECK_EXPECT(MimeFilter_Terminate);
2153 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2155 SET_EXPECT(Terminate);
2156 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2157 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2158 CHECK_CALLED(Terminate);
2160 return S_OK;
2163 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2164 ULONG cb, ULONG *pcbRead)
2166 BYTE buf[2096];
2167 DWORD read = 0;
2168 HRESULT hres;
2170 CHECK_EXPECT(MimeFilter_Read);
2172 ok(pv != NULL, "pv == NULL\n");
2173 ok(cb != 0, "cb == 0\n");
2174 ok(pcbRead != NULL, "pcbRead == NULL\n");
2176 if(read_report_data)
2177 SET_EXPECT(Read2);
2178 else
2179 SET_EXPECT(Read);
2180 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2181 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2182 if(read_report_data)
2183 CHECK_CALLED(Read2);
2184 else
2185 CHECK_CALLED(Read);
2187 if(pcbRead) {
2188 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2189 *pcbRead = read;
2192 memset(pv, 'x', read);
2193 return hres;
2196 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2198 HRESULT hres;
2200 CHECK_EXPECT(MimeFilter_LockRequest);
2202 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2204 SET_EXPECT(LockRequest);
2205 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2206 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2207 CHECK_CALLED(LockRequest);
2209 return S_OK;
2212 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2214 HRESULT hres;
2216 CHECK_EXPECT(MimeFilter_UnlockRequest);
2218 SET_EXPECT(UnlockRequest);
2219 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2220 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2221 CHECK_CALLED(UnlockRequest);
2223 return S_OK;
2226 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2227 MimeProtocol_QueryInterface,
2228 Protocol_AddRef,
2229 Protocol_Release,
2230 MimeProtocol_Start,
2231 Protocol_Continue,
2232 Protocol_Abort,
2233 MimeProtocol_Terminate,
2234 Protocol_Suspend,
2235 Protocol_Resume,
2236 MimeProtocol_Read,
2237 Protocol_Seek,
2238 MimeProtocol_LockRequest,
2239 MimeProtocol_UnlockRequest
2242 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2244 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2246 ok(0, "unexpected call\n");
2247 return E_NOINTERFACE;
2250 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2252 return 2;
2255 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2257 return 1;
2260 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2261 REFIID riid, void **ppv)
2263 CHECK_EXPECT(CreateInstance);
2265 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2266 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2267 ok(ppv != NULL, "ppv == NULL\n");
2269 *ppv = &Protocol;
2270 return S_OK;
2273 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2275 ok(0, "unexpected call\n");
2276 return S_OK;
2279 static const IClassFactoryVtbl ClassFactoryVtbl = {
2280 ClassFactory_QueryInterface,
2281 ClassFactory_AddRef,
2282 ClassFactory_Release,
2283 ClassFactory_CreateInstance,
2284 ClassFactory_LockServer
2287 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2289 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2291 CHECK_EXPECT(MimeFilter_CreateInstance);
2293 ok(!outer, "outer = %p\n", outer);
2294 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2296 *ppv = &MimeProtocol;
2297 return S_OK;
2300 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2301 ClassFactory_QueryInterface,
2302 ClassFactory_AddRef,
2303 ClassFactory_Release,
2304 MimeFilter_CreateInstance,
2305 ClassFactory_LockServer
2308 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2310 #define TEST_BINDING 0x0001
2311 #define TEST_FILTER 0x0002
2312 #define TEST_FIRST_HTTP 0x0004
2313 #define TEST_DIRECT_READ 0x0008
2314 #define TEST_POST 0x0010
2315 #define TEST_EMULATEPROT 0x0020
2316 #define TEST_SHORT_READ 0x0040
2317 #define TEST_REDIRECT 0x0080
2318 #define TEST_ABORT 0x0100
2319 #define TEST_ASYNCREQ 0x0200
2320 #define TEST_USEIURI 0x0400
2321 #define TEST_IMPLPROTEX 0x0800
2322 #define TEST_EMPTY 0x1000
2323 #define TEST_NOMIME 0x2000
2324 #define TEST_FROMCACHE 0x4000
2326 static void register_filter(BOOL do_register)
2328 IInternetSession *session;
2329 HRESULT hres;
2331 hres = pCoInternetGetSession(0, &session, 0);
2332 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2334 if(do_register) {
2335 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2336 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2337 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2338 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2339 }else {
2340 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2341 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2342 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2343 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2346 IInternetSession_Release(session);
2349 static void init_test(int prot, DWORD flags)
2351 tested_protocol = prot;
2352 binding_test = (flags & TEST_BINDING) != 0;
2353 first_data_notif = TRUE;
2354 prot_read = 0;
2355 prot_state = 0;
2356 async_read_pending = TRUE;
2357 mimefilter_test = (flags & TEST_FILTER) != 0;
2358 no_mime = (flags & TEST_NOMIME) != 0;
2359 filter_state = 0;
2360 post_stream_read = 0;
2361 ResetEvent(event_complete);
2362 ResetEvent(event_complete2);
2363 ResetEvent(event_continue);
2364 ResetEvent(event_continue_done);
2365 async_protocol = binding_protocol = filtered_protocol = NULL;
2366 filtered_sink = NULL;
2367 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2368 first_data_notif = TRUE;
2369 state = STATE_CONNECTING;
2370 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2371 direct_read = (flags & TEST_DIRECT_READ) != 0;
2372 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2373 wait_for_switch = TRUE;
2374 short_read = (flags & TEST_SHORT_READ) != 0;
2375 http_post_test = TYMED_NULL;
2376 test_redirect = (flags & TEST_REDIRECT) != 0;
2377 test_abort = (flags & TEST_ABORT) != 0;
2378 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2379 empty_file = (flags & TEST_EMPTY) != 0;
2380 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2382 register_filter(mimefilter_test);
2385 static void test_priority(IInternetProtocol *protocol)
2387 IInternetPriority *priority;
2388 LONG pr;
2389 HRESULT hres;
2391 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2392 (void**)&priority);
2393 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2394 if(FAILED(hres))
2395 return;
2397 hres = IInternetPriority_GetPriority(priority, &pr);
2398 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2399 ok(pr == 0, "pr=%d, expected 0\n", pr);
2401 hres = IInternetPriority_SetPriority(priority, 1);
2402 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2404 hres = IInternetPriority_GetPriority(priority, &pr);
2405 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2406 ok(pr == 1, "pr=%d, expected 1\n", pr);
2408 IInternetPriority_Release(priority);
2411 static void test_early_abort(const CLSID *clsid)
2413 IInternetProtocol *protocol;
2414 HRESULT hres;
2416 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2417 &IID_IInternetProtocol, (void**)&protocol);
2418 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2420 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2421 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2423 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2424 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2426 IInternetProtocol_Release(protocol);
2429 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2430 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2432 HRESULT hres;
2434 SET_EXPECT(GetBindInfo);
2435 if(!(bindf & BINDF_FROMURLMON))
2436 SET_EXPECT(ReportProgress_DIRECTBIND);
2437 if(is_first) {
2438 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2439 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2440 if(bindf & BINDF_FROMURLMON)
2441 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2442 else
2443 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2445 SET_EXPECT(ReportData);
2446 if(is_first)
2447 SET_EXPECT(ReportResult);
2449 expect_hrResult = S_OK;
2451 if(protocolex) {
2452 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2453 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2454 }else {
2455 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2456 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2457 win_skip("Start failed\n");
2458 return FALSE;
2460 ok(hres == S_OK, "Start failed: %08x\n", hres);
2463 CHECK_CALLED(GetBindInfo);
2464 if(!(bindf & BINDF_FROMURLMON))
2465 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2466 if(is_first) {
2467 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2468 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2469 if(bindf & BINDF_FROMURLMON)
2470 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2471 else
2472 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2474 CHECK_CALLED(ReportData);
2475 if(is_first)
2476 CHECK_CALLED(ReportResult);
2478 return TRUE;
2481 static void test_file_protocol_url(LPCWSTR url)
2483 IInternetProtocolInfo *protocol_info;
2484 IUnknown *unk;
2485 IClassFactory *factory;
2486 IInternetProtocol *protocol;
2487 BYTE buf[512];
2488 ULONG cb;
2489 HRESULT hres;
2491 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2492 &IID_IUnknown, (void**)&unk);
2493 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2494 if(FAILED(hres))
2495 return;
2497 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2498 ok(hres == E_NOINTERFACE,
2499 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2501 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2502 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2503 IUnknown_Release(unk);
2504 if(FAILED(hres))
2505 return;
2507 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2508 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2510 if(SUCCEEDED(hres)) {
2511 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2512 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2513 ok(hres == S_OK, "Read failed: %08x\n", hres);
2514 ok(cb == 2, "cb=%u expected 2\n", cb);
2515 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2516 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2517 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2518 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2519 ok(cb == 0, "cb=%u expected 0\n", cb);
2520 hres = IInternetProtocol_UnlockRequest(protocol);
2521 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2524 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2525 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2526 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2527 hres = IInternetProtocol_LockRequest(protocol, 0);
2528 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2529 hres = IInternetProtocol_UnlockRequest(protocol);
2530 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2533 IInternetProtocol_Release(protocol);
2536 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2537 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2538 if(SUCCEEDED(hres)) {
2539 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2540 hres = IInternetProtocol_LockRequest(protocol, 0);
2541 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2542 hres = IInternetProtocol_Terminate(protocol, 0);
2543 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2544 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2545 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2546 hres = IInternetProtocol_UnlockRequest(protocol);
2547 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2548 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2549 ok(hres == S_OK, "Read failed: %08x\n", hres);
2550 hres = IInternetProtocol_Terminate(protocol, 0);
2551 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2554 IInternetProtocol_Release(protocol);
2557 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2558 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2559 if(SUCCEEDED(hres)) {
2560 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2561 hres = IInternetProtocol_Terminate(protocol, 0);
2562 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2563 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2564 ok(hres == S_OK, "Read failed: %08x\n", hres);
2565 ok(cb == 2, "cb=%u expected 2\n", cb);
2568 IInternetProtocol_Release(protocol);
2571 if(pCreateUri) {
2572 IInternetProtocolEx *protocolex;
2573 IUri *uri;
2575 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2576 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2578 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2579 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2581 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2582 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2583 ok(hres == S_OK, "Read failed: %08x\n", hres);
2584 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2585 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2586 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2587 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2590 IUri_Release(uri);
2591 IInternetProtocolEx_Release(protocolex);
2593 hres = pCreateUri(url, 0, 0, &uri);
2594 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2596 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2597 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2599 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2600 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2601 ok(hres == S_OK, "Read failed: %08x\n", hres);
2602 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2603 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2604 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2605 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2608 IUri_Release(uri);
2609 IInternetProtocolEx_Release(protocolex);
2610 }else {
2611 win_skip("Skipping file protocol StartEx tests\n");
2614 IClassFactory_Release(factory);
2617 static void test_file_protocol_fail(void)
2619 IInternetProtocol *protocol;
2620 HRESULT hres;
2622 static const WCHAR index_url2[] =
2623 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2625 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2626 &IID_IInternetProtocol, (void**)&protocol);
2627 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2628 if(FAILED(hres))
2629 return;
2631 SET_EXPECT(GetBindInfo);
2632 expect_hrResult = MK_E_SYNTAX;
2633 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2634 ok(hres == MK_E_SYNTAX ||
2635 hres == E_INVALIDARG,
2636 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2637 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2639 SET_EXPECT(GetBindInfo);
2640 if(!(bindf & BINDF_FROMURLMON))
2641 SET_EXPECT(ReportProgress_DIRECTBIND);
2642 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2643 SET_EXPECT(ReportResult);
2644 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2645 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2646 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2647 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2648 CHECK_CALLED(GetBindInfo);
2649 if(!(bindf & BINDF_FROMURLMON))
2650 CHECK_CALLED(ReportProgress_DIRECTBIND);
2651 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2652 CHECK_CALLED(ReportResult);
2654 IInternetProtocol_Release(protocol);
2656 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2657 &IID_IInternetProtocol, (void**)&protocol);
2658 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2659 if(FAILED(hres))
2660 return;
2662 SET_EXPECT(GetBindInfo);
2663 if(!(bindf & BINDF_FROMURLMON))
2664 SET_EXPECT(ReportProgress_DIRECTBIND);
2665 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2666 SET_EXPECT(ReportResult);
2667 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2669 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2670 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2671 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2672 CHECK_CALLED(GetBindInfo);
2673 if(!(bindf & BINDF_FROMURLMON))
2674 CHECK_CALLED(ReportProgress_DIRECTBIND);
2675 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2676 CHECK_CALLED(ReportResult);
2678 SET_EXPECT(GetBindInfo);
2679 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2680 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2681 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2683 SET_EXPECT(GetBindInfo);
2684 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2685 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2686 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2688 IInternetProtocol_Release(protocol);
2691 static void test_file_protocol(void) {
2692 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2693 DWORD size;
2694 ULONG len;
2695 HANDLE file;
2697 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2698 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2699 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2700 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2701 static const char html_doc[] = "<HTML></HTML>";
2703 trace("Testing file protocol...\n");
2704 init_test(FILE_TEST, 0);
2706 SetLastError(0xdeadbeef);
2707 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2708 FILE_ATTRIBUTE_NORMAL, NULL);
2709 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2710 if(file == INVALID_HANDLE_VALUE)
2711 return;
2712 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2713 CloseHandle(file);
2715 file_name = wszIndexHtml;
2716 bindf = 0;
2717 test_file_protocol_url(index_url);
2718 bindf = BINDF_FROMURLMON;
2719 test_file_protocol_url(index_url);
2720 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2721 test_file_protocol_url(index_url);
2723 memcpy(buf, wszFile, sizeof(wszFile));
2724 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2725 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2726 buf[len++] = '\\';
2727 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2729 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2730 bindf = 0;
2731 test_file_protocol_url(buf);
2732 bindf = BINDF_FROMURLMON;
2733 test_file_protocol_url(buf);
2735 memcpy(buf, wszFile2, sizeof(wszFile2));
2736 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2737 file_name_buf[len++] = '\\';
2738 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2739 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2740 file_name = file_name_buf;
2741 bindf = 0;
2742 test_file_protocol_url(buf);
2743 bindf = BINDF_FROMURLMON;
2744 test_file_protocol_url(buf);
2746 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2747 test_file_protocol_url(buf);
2749 memcpy(buf, wszFile3, sizeof(wszFile3));
2750 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2751 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2752 buf[len++] = '\\';
2753 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2755 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2756 bindf = 0;
2757 test_file_protocol_url(buf);
2758 bindf = BINDF_FROMURLMON;
2759 test_file_protocol_url(buf);
2761 memcpy(buf, wszFile4, sizeof(wszFile4));
2762 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2763 file_name_buf[len++] = '\\';
2764 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2765 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2766 file_name = file_name_buf;
2767 bindf = 0;
2768 test_file_protocol_url(buf);
2769 bindf = BINDF_FROMURLMON;
2770 test_file_protocol_url(buf);
2772 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2773 test_file_protocol_url(buf);
2775 DeleteFileW(wszIndexHtml);
2777 bindf = 0;
2778 test_file_protocol_fail();
2779 bindf = BINDF_FROMURLMON;
2780 test_file_protocol_fail();
2783 static void create_cache_entry(const WCHAR *urlw)
2785 FILETIME now, tomorrow, yesterday;
2786 char file_path[MAX_PATH];
2787 BYTE content[1000];
2788 ULARGE_INTEGER li;
2789 const char *url;
2790 HANDLE file;
2791 DWORD size;
2792 unsigned i;
2793 BOOL res;
2795 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2797 trace("Testing cache read...\n");
2799 url = w2a(urlw);
2801 for(i = 0; i < sizeof(content); i++)
2802 content[i] = '0' + (i%10);
2804 GetSystemTimeAsFileTime(&now);
2805 li.u.HighPart = now.dwHighDateTime;
2806 li.u.LowPart = now.dwLowDateTime;
2807 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2808 tomorrow.dwHighDateTime = li.u.HighPart;
2809 tomorrow.dwLowDateTime = li.u.LowPart;
2810 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2811 yesterday.dwHighDateTime = li.u.HighPart;
2812 yesterday.dwLowDateTime = li.u.LowPart;
2814 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2815 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2817 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2818 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2820 WriteFile(file, content, sizeof(content), &size, NULL);
2821 CloseHandle(file);
2823 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2824 cache_headers, sizeof(cache_headers)-1, "", 0);
2825 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2828 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2830 static BOOL got_user_agent = FALSE;
2831 IUri *uri = NULL;
2832 HRESULT hres;
2834 if(use_iuri && pCreateUri) {
2835 hres = pCreateUri(url, 0, 0, &uri);
2836 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2839 SET_EXPECT(GetBindInfo);
2840 if (!(bindf & BINDF_FROMURLMON))
2841 SET_EXPECT(ReportProgress_DIRECTBIND);
2842 if(!got_user_agent)
2843 SET_EXPECT(GetBindString_USER_AGENT);
2844 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2845 SET_EXPECT(QueryService_HttpNegotiate);
2846 SET_EXPECT(BeginningTransaction);
2847 SET_EXPECT(GetRootSecurityId);
2848 if(http_post_test) {
2849 SET_EXPECT(GetBindString_POST_COOKIE);
2850 if(http_post_test == TYMED_ISTREAM)
2851 SET_EXPECT(Stream_Seek);
2853 if(bind_from_cache) {
2854 SET_EXPECT(OnResponse);
2855 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2856 SET_EXPECT(ReportData);
2859 if(uri) {
2860 IInternetProtocolEx *protocolex;
2862 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2863 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2865 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2866 ok(hres == S_OK, "Start failed: %08x\n", hres);
2868 IInternetProtocolEx_Release(protocolex);
2869 IUri_Release(uri);
2870 }else {
2871 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2872 ok(hres == S_OK, "Start failed: %08x\n", hres);
2874 if(FAILED(hres))
2875 return FALSE;
2877 CHECK_CALLED(GetBindInfo);
2878 if (!(bindf & BINDF_FROMURLMON))
2879 CHECK_CALLED(ReportProgress_DIRECTBIND);
2880 if (!got_user_agent)
2882 CHECK_CALLED(GetBindString_USER_AGENT);
2883 got_user_agent = TRUE;
2885 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2886 CHECK_CALLED(QueryService_HttpNegotiate);
2887 CHECK_CALLED(BeginningTransaction);
2888 /* GetRootSecurityId called on WinXP but not on Win98 */
2889 CLEAR_CALLED(GetRootSecurityId);
2890 if(http_post_test) {
2891 CHECK_CALLED(GetBindString_POST_COOKIE);
2892 if(http_post_test == TYMED_ISTREAM)
2893 CHECK_CALLED(Stream_Seek);
2895 if(bind_from_cache) {
2896 CHECK_CALLED(OnResponse);
2897 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2898 CHECK_CALLED(ReportData);
2901 return TRUE;
2904 static void test_protocol_terminate(IInternetProtocol *protocol)
2906 BYTE buf[3600];
2907 DWORD cb;
2908 HRESULT hres;
2910 hres = IInternetProtocol_LockRequest(protocol, 0);
2911 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2913 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2914 ok(hres == test_abort ? S_OK : S_FALSE, "Read failed: %08x\n", hres);
2916 hres = IInternetProtocol_Terminate(protocol, 0);
2917 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2919 /* This wait is to give the internet handles being freed in Terminate
2920 * enough time to actually terminate in all cases. Internet handles
2921 * terminate asynchronously and native reuses the main InternetOpen
2922 * handle. The only case in which this seems to be necessary is on
2923 * wine with native wininet and urlmon, resulting in the next time
2924 * test_http_protocol_url being called the first data notification actually
2925 * being an extra last data notification from the previous connection
2926 * about once out of every ten times. */
2927 Sleep(100);
2929 hres = IInternetProtocol_UnlockRequest(protocol);
2930 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2933 static void test_http_info(IInternetProtocol *protocol)
2935 IWinInetHttpInfo *info;
2936 HRESULT hres;
2938 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2939 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2941 /* TODO */
2943 IWinInetHttpInfo_Release(info);
2946 /* is_first refers to whether this is the first call to this function
2947 * _for this url_ */
2948 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
2950 IInternetProtocolInfo *protocol_info;
2951 IClassFactory *factory;
2952 IUnknown *unk;
2953 HRESULT hres;
2955 init_test(prot, flags);
2956 http_url = url;
2957 http_post_test = tymed;
2959 if(flags & TEST_FROMCACHE)
2960 create_cache_entry(url);
2962 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
2963 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
2964 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2965 if(FAILED(hres))
2966 return;
2968 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2969 ok(hres == E_NOINTERFACE,
2970 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
2971 hres);
2973 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2974 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2975 IUnknown_Release(unk);
2976 if(FAILED(hres))
2977 return;
2979 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
2980 (void**)&async_protocol);
2981 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2982 if(SUCCEEDED(hres)) {
2983 BYTE buf[3600];
2984 DWORD cb;
2985 ULONG ref;
2987 test_priority(async_protocol);
2988 test_http_info(async_protocol);
2990 SET_EXPECT(ReportProgress_COOKIE_SENT);
2991 if(http_is_first) {
2992 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
2993 SET_EXPECT(ReportProgress_CONNECTING);
2995 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2996 if(test_redirect)
2997 SET_EXPECT(ReportProgress_REDIRECTING);
2998 SET_EXPECT(ReportProgress_PROXYDETECTING);
2999 if(prot == HTTP_TEST)
3000 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3001 else
3002 SET_EXPECT(QueryService_HttpSecurity);
3003 if(!(bindf & BINDF_FROMURLMON)) {
3004 SET_EXPECT(OnResponse);
3005 SET_EXPECT(ReportProgress_RAWMIMETYPE);
3006 SET_EXPECT(ReportData);
3007 } else {
3008 SET_EXPECT(Switch);
3011 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3012 IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3013 IInternetProtocol_Release(async_protocol);
3014 return;
3017 if(!direct_read && !test_abort && !bind_from_cache)
3018 SET_EXPECT(ReportResult);
3019 expect_hrResult = test_abort ? E_ABORT : S_OK;
3021 if(direct_read) {
3022 SET_EXPECT(Switch);
3023 while(wait_for_switch) {
3024 ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3025 CHECK_CALLED(Switch); /* Set in ReportData */
3026 call_continue(&continue_protdata);
3027 SetEvent(event_continue_done);
3029 }else if(bind_from_cache) {
3030 BYTE buf[1500];
3032 hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3033 ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3035 SET_EXPECT(ReportResult);
3036 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3037 ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3038 CHECK_CALLED(ReportResult);
3040 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3041 ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3042 }else {
3043 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3044 ok((hres == E_PENDING && cb==0) ||
3045 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3047 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3048 if(bindf & BINDF_FROMURLMON)
3049 CHECK_CALLED(Switch);
3050 else
3051 CHECK_CALLED(ReportData);
3052 if(prot == HTTPS_TEST)
3053 CLEAR_CALLED(QueryService_HttpSecurity);
3055 while(1) {
3056 if(bindf & BINDF_FROMURLMON)
3057 SET_EXPECT(Switch);
3058 else
3059 SET_EXPECT(ReportData);
3060 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3061 if(hres == E_PENDING) {
3062 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3063 ok((hres == E_PENDING && cb==0) ||
3064 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3065 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3066 if(bindf & BINDF_FROMURLMON)
3067 CHECK_CALLED(Switch);
3068 else
3069 CHECK_CALLED(ReportData);
3071 if(test_abort) {
3072 HRESULT hres;
3074 SET_EXPECT(ReportResult);
3075 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3076 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3077 CHECK_CALLED(ReportResult);
3079 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3080 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3081 break;
3083 }else {
3084 if(bindf & BINDF_FROMURLMON)
3085 CHECK_NOT_CALLED(Switch);
3086 else
3087 CHECK_NOT_CALLED(ReportData);
3088 if(cb == 0) break;
3091 if(!test_abort) {
3092 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3093 CHECK_CALLED(ReportResult);
3096 if(prot == HTTPS_TEST)
3097 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3099 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3100 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3102 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3103 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3105 test_protocol_terminate(async_protocol);
3107 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3108 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3110 ref = IInternetProtocol_Release(async_protocol);
3111 ok(!ref, "ref=%x\n", ref);
3114 IClassFactory_Release(factory);
3116 if(flags & TEST_FROMCACHE) {
3117 BOOL res;
3119 res = DeleteUrlCacheEntryW(url);
3120 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3124 static void test_http_protocol(void)
3126 static const WCHAR posttest_url[] =
3127 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3128 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3129 static const WCHAR redirect_url[] =
3130 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3131 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3132 static const WCHAR winetest_url[] =
3133 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3134 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3135 static const WCHAR empty_url[] =
3136 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3137 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3138 static const WCHAR cache_only_url[] =
3139 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3140 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3143 trace("Testing http protocol (not from urlmon)...\n");
3144 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3145 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3147 trace("Testing http protocol (from urlmon)...\n");
3148 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3149 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3151 trace("Testing http protocol (to file)...\n");
3152 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3153 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3155 trace("Testing http protocol (post data)...\n");
3156 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3157 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3159 trace("Testing http protocol (post data stream)...\n");
3160 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3162 trace("Testing http protocol (direct read)...\n");
3163 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3164 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3166 trace("Testing http protocol (redirected)...\n");
3167 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3168 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3170 trace("Testing http protocol empty file...\n");
3171 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3172 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3174 /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3175 * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3176 * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3177 * tests work on Windows and have them around for the future.
3179 if(broken(1)) {
3180 trace("Testing http protocol (from cache)...\n");
3181 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3182 test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3185 trace("Testing http protocol abort...\n");
3186 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3187 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3189 test_early_abort(&CLSID_HttpProtocol);
3190 test_early_abort(&CLSID_HttpSProtocol);
3193 static void test_https_protocol(void)
3195 static const WCHAR codeweavers_url[] =
3196 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
3197 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0};
3199 trace("Testing https protocol (from urlmon)...\n");
3200 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3201 test_http_protocol_url(codeweavers_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3205 static void test_ftp_protocol(void)
3207 IInternetProtocolInfo *protocol_info;
3208 IClassFactory *factory;
3209 IUnknown *unk;
3210 BYTE buf[4096];
3211 ULONG ref;
3212 DWORD cb;
3213 HRESULT hres;
3215 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3216 '/','p','u','b','/','o','t','h','e','r','/',
3217 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3219 trace("Testing ftp protocol...\n");
3221 init_test(FTP_TEST, 0);
3223 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3224 state = STATE_STARTDOWNLOADING;
3225 expect_hrResult = E_PENDING;
3227 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3228 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3229 if(FAILED(hres))
3230 return;
3232 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3233 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3235 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3236 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3237 IUnknown_Release(unk);
3238 if(FAILED(hres))
3239 return;
3241 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3242 (void**)&async_protocol);
3243 IClassFactory_Release(factory);
3244 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3246 test_priority(async_protocol);
3247 test_http_info(async_protocol);
3249 SET_EXPECT(GetBindInfo);
3250 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3251 SET_EXPECT(ReportProgress_CONNECTING);
3252 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3253 SET_EXPECT(Switch);
3255 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
3256 ok(hres == S_OK, "Start failed: %08x\n", hres);
3257 CHECK_CALLED(GetBindInfo);
3259 SET_EXPECT(ReportResult);
3261 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3262 ok((hres == E_PENDING && cb==0) ||
3263 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3265 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3267 while(1) {
3268 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3269 if(hres == E_PENDING)
3271 DWORD ret = WaitForSingleObject(event_complete, 90000);
3272 ok( ret == WAIT_OBJECT_0, "wait timed out\n" );
3273 if (ret != WAIT_OBJECT_0) break;
3275 else
3276 if(cb == 0) break;
3279 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3280 CHECK_CALLED(ReportResult);
3281 CHECK_CALLED(Switch);
3283 test_protocol_terminate(async_protocol);
3285 if(pCreateUri) {
3286 IInternetProtocolEx *protocolex;
3288 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3289 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3290 IInternetProtocolEx_Release(protocolex);
3293 ref = IInternetProtocol_Release(async_protocol);
3294 ok(!ref, "ref=%d\n", ref);
3296 test_early_abort(&CLSID_FtpProtocol);
3299 static void test_gopher_protocol(void)
3301 IInternetProtocolInfo *protocol_info;
3302 IClassFactory *factory;
3303 IUnknown *unk;
3304 HRESULT hres;
3306 trace("Testing gopher protocol...\n");
3308 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3309 ok(hres == S_OK ||
3310 broken(hres == REGDB_E_CLASSNOTREG || hres == CLASS_E_CLASSNOTAVAILABLE), /* Gopher protocol has been removed as of Vista */
3311 "CoGetClassObject failed: %08x\n", hres);
3312 if(FAILED(hres))
3313 return;
3315 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3316 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3318 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3319 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3320 IUnknown_Release(unk);
3321 if(FAILED(hres))
3322 return;
3324 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3325 (void**)&async_protocol);
3326 IClassFactory_Release(factory);
3327 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3329 test_priority(async_protocol);
3331 IInternetProtocol_Release(async_protocol);
3333 test_early_abort(&CLSID_GopherProtocol);
3336 static void test_mk_protocol(void)
3338 IInternetProtocolInfo *protocol_info;
3339 IInternetProtocol *protocol;
3340 IClassFactory *factory;
3341 IUnknown *unk;
3342 HRESULT hres;
3344 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
3345 ':',':','/','t','e','s','t','.','h','t','m','l',0};
3346 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
3348 trace("Testing mk protocol...\n");
3349 init_test(MK_TEST, 0);
3351 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
3352 &IID_IUnknown, (void**)&unk);
3353 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3355 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3356 ok(hres == E_NOINTERFACE,
3357 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3358 hres);
3360 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3361 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3362 IUnknown_Release(unk);
3363 if(FAILED(hres))
3364 return;
3366 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3367 (void**)&protocol);
3368 IClassFactory_Release(factory);
3369 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3371 SET_EXPECT(GetBindInfo);
3372 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
3373 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
3374 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
3375 CLEAR_CALLED(GetBindInfo);
3377 SET_EXPECT(GetBindInfo);
3378 SET_EXPECT(ReportProgress_DIRECTBIND);
3379 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3380 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3381 SET_EXPECT(ReportResult);
3382 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3384 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
3385 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
3386 hres == INET_E_INVALID_URL, /* win2k3 */
3387 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
3389 if (hres == INET_E_RESOURCE_NOT_FOUND) {
3390 CHECK_CALLED(GetBindInfo);
3391 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3392 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3393 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3394 CHECK_CALLED(ReportResult);
3395 }else {
3396 CLEAR_CALLED(GetBindInfo);
3397 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3398 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3399 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3400 CLEAR_CALLED(ReportResult);
3403 IInternetProtocol_Release(protocol);
3406 static void test_CreateBinding(void)
3408 IInternetProtocol *protocol;
3409 IInternetPriority *priority;
3410 IInternetSession *session;
3411 IWinInetHttpInfo *http_info;
3412 IWinInetInfo *inet_info;
3413 LONG p;
3414 BYTE buf[1000];
3415 DWORD read;
3416 HRESULT hres;
3418 static const WCHAR test_url[] =
3419 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
3420 static const WCHAR wsz_test[] = {'t','e','s','t',0};
3422 trace("Testing CreateBinding...\n");
3423 init_test(BIND_TEST, TEST_BINDING);
3425 hres = pCoInternetGetSession(0, &session, 0);
3426 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3428 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
3429 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3431 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3432 binding_protocol = protocol;
3433 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3434 ok(protocol != NULL, "protocol == NULL\n");
3436 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3437 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3439 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3440 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
3442 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
3443 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3444 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
3445 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3446 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3447 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3449 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
3450 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
3452 p = 0xdeadbeef;
3453 hres = IInternetPriority_GetPriority(priority, &p);
3454 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3455 ok(!p, "p=%d\n", p);
3457 ex_priority = 100;
3458 hres = IInternetPriority_SetPriority(priority, 100);
3459 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3461 p = 0xdeadbeef;
3462 hres = IInternetPriority_GetPriority(priority, &p);
3463 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3464 ok(p == 100, "p=%d\n", p);
3466 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3467 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3469 SET_EXPECT(QueryService_InternetProtocol);
3470 SET_EXPECT(CreateInstance);
3471 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3472 SET_EXPECT(SetPriority);
3473 SET_EXPECT(Start);
3475 expect_hrResult = S_OK;
3476 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3477 ok(hres == S_OK, "Start failed: %08x\n", hres);
3479 CHECK_CALLED(QueryService_InternetProtocol);
3480 CHECK_CALLED(CreateInstance);
3481 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3482 CHECK_CALLED(SetPriority);
3483 CHECK_CALLED(Start);
3485 SET_EXPECT(QueryInterface_IWinInetInfo);
3486 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3487 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3488 CHECK_CALLED(QueryInterface_IWinInetInfo);
3490 SET_EXPECT(QueryInterface_IWinInetInfo);
3491 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3492 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3493 CHECK_CALLED(QueryInterface_IWinInetInfo);
3495 SET_EXPECT(QueryInterface_IWinInetHttpInfo);
3496 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
3497 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3498 CHECK_CALLED(QueryInterface_IWinInetHttpInfo);
3500 SET_EXPECT(Read);
3501 read = 0xdeadbeef;
3502 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3503 ok(hres == S_OK, "Read failed: %08x\n", hres);
3504 ok(read == 100, "read = %d\n", read);
3505 CHECK_CALLED(Read);
3507 SET_EXPECT(Read);
3508 read = 0xdeadbeef;
3509 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3510 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3511 ok(!read, "read = %d\n", read);
3512 CHECK_CALLED(Read);
3514 p = 0xdeadbeef;
3515 hres = IInternetPriority_GetPriority(priority, &p);
3516 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3517 ok(p == 100, "p=%d\n", p);
3519 hres = IInternetPriority_SetPriority(priority, 101);
3520 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3522 SET_EXPECT(Terminate);
3523 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
3524 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3525 CHECK_CALLED(Terminate);
3527 SET_EXPECT(Continue);
3528 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
3529 ok(hres == S_OK, "Switch failed: %08x\n", hres);
3530 CHECK_CALLED(Continue);
3532 hres = IInternetProtocolSink_ReportProgress(binding_sink,
3533 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
3534 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
3536 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
3537 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
3539 hres = IInternetProtocolSink_ReportData(binding_sink, 0, 0, 0);
3540 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
3542 IInternetProtocolSink_Release(binding_sink);
3543 IInternetPriority_Release(priority);
3544 IInternetBindInfo_Release(prot_bind_info);
3545 IInternetProtocol_Release(protocol);
3547 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3548 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3549 ok(protocol != NULL, "protocol == NULL\n");
3551 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3552 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3554 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
3555 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3557 IInternetProtocol_Release(protocol);
3559 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, wsz_test);
3560 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3562 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3563 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3564 ok(protocol != NULL, "protocol == NULL\n");
3566 SET_EXPECT(QueryService_InternetProtocol);
3567 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3568 ok(hres == MK_E_SYNTAX, "Start failed: %08x, expected MK_E_SYNTAX\n", hres);
3569 CHECK_CALLED(QueryService_InternetProtocol);
3571 IInternetProtocol_Release(protocol);
3573 IInternetSession_Release(session);
3576 static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
3578 IInternetProtocolEx *protocolex = NULL;
3579 IInternetProtocol *protocol;
3580 IInternetSession *session;
3581 IUri *uri = NULL;
3582 ULONG ref;
3583 HRESULT hres;
3585 pi = grf_pi;
3587 init_test(prot, test_flags|TEST_BINDING);
3589 hres = pCoInternetGetSession(0, &session, 0);
3590 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3592 if(test_flags & TEST_EMULATEPROT) {
3593 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
3594 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3597 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
3598 binding_protocol = protocol;
3599 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3600 ok(protocol != NULL, "protocol == NULL\n");
3602 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3603 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3605 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3606 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
3608 if(test_flags & TEST_USEIURI) {
3609 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3610 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3612 hres = pCreateUri(binding_urls[prot], Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
3613 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3616 ex_priority = 0;
3617 SET_EXPECT(QueryService_InternetProtocol);
3618 SET_EXPECT(CreateInstance);
3619 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3620 SET_EXPECT(SetPriority);
3621 if(impl_protex)
3622 SET_EXPECT(StartEx);
3623 else
3624 SET_EXPECT(Start);
3626 expect_hrResult = S_OK;
3628 if(protocolex) {
3629 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, pi, 0);
3630 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
3631 }else {
3632 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0);
3633 ok(hres == S_OK, "Start failed: %08x\n", hres);
3636 CHECK_CALLED(QueryService_InternetProtocol);
3637 CHECK_CALLED(CreateInstance);
3638 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3639 CHECK_CALLED(SetPriority);
3640 if(impl_protex)
3641 CHECK_CALLED(StartEx);
3642 else
3643 CHECK_CALLED(Start);
3645 if(protocolex)
3646 IInternetProtocolEx_Release(protocolex);
3647 if(uri)
3648 IUri_Release(uri);
3650 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
3651 while(prot_state < 4) {
3652 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3653 if(mimefilter_test && filtered_protocol) {
3654 SET_EXPECT(Continue);
3655 IInternetProtocol_Continue(filtered_protocol, pdata);
3656 CHECK_CALLED(Continue);
3657 }else {
3658 SET_EXPECT(Continue);
3659 IInternetProtocol_Continue(protocol, pdata);
3660 CHECK_CALLED(Continue);
3662 if(test_abort && prot_state == 2) {
3663 SET_EXPECT(Abort);
3664 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3665 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3666 CHECK_CALLED(Abort);
3668 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3669 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3670 SetEvent(event_complete2);
3671 break;
3673 SetEvent(event_complete2);
3675 if(direct_read)
3676 CHECK_CALLED(ReportData); /* Set in ReportResult */
3677 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3678 }else {
3679 if(mimefilter_test)
3680 SET_EXPECT(MimeFilter_LockRequest);
3681 else
3682 SET_EXPECT(LockRequest);
3683 hres = IInternetProtocol_LockRequest(protocol, 0);
3684 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3685 if(mimefilter_test)
3686 CHECK_CALLED(MimeFilter_LockRequest);
3687 else
3688 CHECK_CALLED(LockRequest);
3690 if(mimefilter_test)
3691 SET_EXPECT(MimeFilter_UnlockRequest);
3692 else
3693 SET_EXPECT(UnlockRequest);
3694 hres = IInternetProtocol_UnlockRequest(protocol);
3695 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3696 if(mimefilter_test)
3697 CHECK_CALLED(MimeFilter_UnlockRequest);
3698 else
3699 CHECK_CALLED(UnlockRequest);
3702 if(mimefilter_test)
3703 SET_EXPECT(MimeFilter_Terminate);
3704 else
3705 SET_EXPECT(Terminate);
3706 hres = IInternetProtocol_Terminate(protocol, 0);
3707 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3708 if(mimefilter_test)
3709 CLEAR_CALLED(MimeFilter_Terminate);
3710 else
3711 CHECK_CALLED(Terminate);
3713 if(filtered_protocol)
3714 IInternetProtocol_Release(filtered_protocol);
3715 IInternetBindInfo_Release(prot_bind_info);
3716 IInternetProtocolSink_Release(binding_sink);
3717 ref = IInternetProtocol_Release(protocol);
3718 ok(!ref, "ref=%u, expected 0\n", ref);
3720 if(test_flags & TEST_EMULATEPROT) {
3721 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]);
3722 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3725 IInternetSession_Release(session);
3728 START_TEST(protocol)
3730 HMODULE hurlmon;
3732 hurlmon = GetModuleHandleA("urlmon.dll");
3733 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
3734 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
3735 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3737 if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3738 win_skip("Various needed functions not present, too old IE\n");
3739 return;
3742 if(!pCreateUri)
3743 win_skip("CreateUri not supported\n");
3745 OleInitialize(NULL);
3747 event_complete = CreateEventW(NULL, FALSE, FALSE, NULL);
3748 event_complete2 = CreateEventW(NULL, FALSE, FALSE, NULL);
3749 event_continue = CreateEventW(NULL, FALSE, FALSE, NULL);
3750 event_continue_done = CreateEventW(NULL, FALSE, FALSE, NULL);
3751 thread_id = GetCurrentThreadId();
3753 test_file_protocol();
3754 test_http_protocol();
3755 if(pCreateUri)
3756 test_https_protocol();
3757 else
3758 win_skip("Skipping https tests on too old platform\n");
3759 test_ftp_protocol();
3760 test_gopher_protocol();
3761 test_mk_protocol();
3762 test_CreateBinding();
3764 bindf &= ~BINDF_FROMURLMON;
3765 trace("Testing file binding (mime verification, emulate prot)...\n");
3766 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3767 trace("Testing http binding (mime verification, emulate prot)...\n");
3768 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3769 trace("Testing its binding (mime verification, emulate prot)...\n");
3770 test_binding(ITS_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3771 trace("Testing http binding (mime verification, emulate prot, short read, direct read)...\n");
3772 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_SHORT_READ|TEST_DIRECT_READ);
3773 trace("Testing file binding (mime verification, emulate prot, mime filter)...\n");
3774 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3775 trace("Testing http binding (mime verification, emulate prot, mime filter)...\n");
3776 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3777 trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n");
3778 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME);
3779 trace("Testing http binding (mime verification, emulate prot, direct read)...\n");
3780 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
3781 trace("Testing http binding (mime verification, emulate prot, abort)...\n");
3782 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
3783 if(pCreateUri) {
3784 trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
3785 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);
3786 trace("Testing file binding (use IUri, impl StartEx, mime verification, emulate prot)...\n");
3787 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI|TEST_IMPLPROTEX);
3788 trace("Testing file binding (impl StartEx, mime verification, emulate prot)...\n");
3789 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_IMPLPROTEX);
3792 CloseHandle(event_complete);
3793 CloseHandle(event_complete2);
3794 CloseHandle(event_continue);
3795 CloseHandle(event_continue_done);
3797 OleUninitialize();