urlmon/tests: Remove stray ok() call.
[wine/multimedia.git] / dlls / urlmon / tests / protocol.c
blob889f3a9e0a73387230181a53d9aff2c722666f92
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;
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 const char *debugstr_guid(REFIID riid)
202 static char buf[50];
204 sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
205 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
206 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
207 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
209 return buf;
212 static int strcmp_wa(LPCWSTR strw, const char *stra)
214 CHAR buf[512];
215 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
216 return lstrcmpA(stra, buf);
219 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
221 if(IsEqualGUID(&IID_IUnknown, riid)
222 || IsEqualGUID(&IID_IHttpSecurity, riid)) {
223 *ppv = iface;
224 return S_OK;
227 ok(0, "unexpected call\n");
228 return E_NOINTERFACE;
231 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
233 return 2;
236 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
238 return 1;
241 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
243 trace("HttpSecurity_GetWindow\n");
245 return S_FALSE;
248 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
250 trace("Security problem: %u\n", dwProblem);
251 ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED, "Expected ERROR_INTERNET_SEC_CERT_REV_FAILED got %u\n", dwProblem);
253 /* Only retry once */
254 if (security_problem)
255 return E_ABORT;
257 security_problem = TRUE;
258 SET_EXPECT(BeginningTransaction);
260 return RPC_E_RETRY;
263 static IHttpSecurityVtbl HttpSecurityVtbl = {
264 HttpSecurity_QueryInterface,
265 HttpSecurity_AddRef,
266 HttpSecurity_Release,
267 HttpSecurity_GetWindow,
268 HttpSecurity_OnSecurityProblem
271 static IHttpSecurity http_security = { &HttpSecurityVtbl };
273 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
275 if(IsEqualGUID(&IID_IUnknown, riid)
276 || IsEqualGUID(&IID_IHttpNegotiate, riid)
277 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
278 *ppv = iface;
279 return S_OK;
282 ok(0, "unexpected call\n");
283 return E_NOINTERFACE;
286 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
288 return 2;
291 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
293 return 1;
296 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
297 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
299 LPWSTR addl_headers;
301 static const WCHAR wszHeaders[] =
302 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
303 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
304 'd','e','d','\r','\n',0};
306 CHECK_EXPECT(BeginningTransaction);
308 if(binding_test)
309 ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
310 else
311 ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
312 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
313 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
314 if(pszAdditionalHeaders)
316 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
317 if (http_post_test)
319 addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
320 memcpy(addl_headers, wszHeaders, sizeof(wszHeaders));
321 *pszAdditionalHeaders = addl_headers;
325 return S_OK;
328 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
329 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
331 CHECK_EXPECT(OnResponse);
333 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
334 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
335 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
336 ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
338 return S_OK;
341 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
342 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
344 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
346 CHECK_EXPECT(GetRootSecurityId);
348 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
349 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
350 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
352 if(pcbSecurityId) {
353 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
354 *pcbSecurityId = sizeof(sec_id);
357 if(pbSecurityId)
358 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
360 return E_FAIL;
363 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
364 HttpNegotiate_QueryInterface,
365 HttpNegotiate_AddRef,
366 HttpNegotiate_Release,
367 HttpNegotiate_BeginningTransaction,
368 HttpNegotiate_OnResponse,
369 HttpNegotiate_GetRootSecurityId
372 static IHttpNegotiate2 http_negotiate = { &HttpNegotiateVtbl };
374 static HRESULT QueryInterface(REFIID,void**);
376 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
378 return QueryInterface(riid, ppv);
381 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
383 return 2;
386 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
388 return 1;
391 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
392 REFIID riid, void **ppv)
394 if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
395 CHECK_EXPECT2(QueryService_HttpNegotiate);
396 return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
399 if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
400 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
401 CHECK_EXPECT(QueryService_InternetProtocol);
402 return E_NOINTERFACE;
405 if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
406 ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
407 CHECK_EXPECT(QueryService_HttpSecurity);
408 return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
411 ok(0, "unexpected service %s\n", debugstr_guid(guidService));
412 return E_FAIL;
415 static const IServiceProviderVtbl ServiceProviderVtbl = {
416 ServiceProvider_QueryInterface,
417 ServiceProvider_AddRef,
418 ServiceProvider_Release,
419 ServiceProvider_QueryService
422 static IServiceProvider service_provider = { &ServiceProviderVtbl };
424 static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
426 ok(0, "unexpected call\n");
427 return E_NOINTERFACE;
430 static ULONG WINAPI Stream_AddRef(IStream *iface)
432 return 2;
435 static ULONG WINAPI Stream_Release(IStream *iface)
437 return 1;
440 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
441 ULONG cb, ULONG *pcbRead)
443 CHECK_EXPECT2(Stream_Read);
445 ok(GetCurrentThreadId() != thread_id, "wrong thread %d\n", GetCurrentThreadId());
447 ok(pv != NULL, "pv == NULL\n");
448 ok(cb == 0x20000 || broken(cb == 0x2000), "cb = %d\n", cb);
449 ok(pcbRead != NULL, "pcbRead == NULL\n");
451 if(post_stream_read) {
452 *pcbRead = 0;
453 return S_FALSE;
456 memcpy(pv, post_data, sizeof(post_data)-1);
457 post_stream_read += *pcbRead = sizeof(post_data)-1;
458 return S_OK;
461 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
462 ULONG cb, ULONG *pcbWritten)
464 ok(0, "unexpected call\n");
465 return E_NOTIMPL;
468 static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
469 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
471 CHECK_EXPECT(Stream_Seek);
473 ok(!dlibMove.QuadPart, "dlibMove != 0\n");
474 ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
475 ok(!plibNewPosition, "plibNewPosition == NULL\n");
477 return S_OK;
480 static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
482 ok(0, "unexpected call\n");
483 return E_NOTIMPL;
486 static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm,
487 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
489 ok(0, "unexpected call\n");
490 return E_NOTIMPL;
493 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
495 ok(0, "unexpected call\n");
496 return E_NOTIMPL;
499 static HRESULT WINAPI Stream_Revert(IStream *iface)
501 ok(0, "unexpected call\n");
502 return E_NOTIMPL;
505 static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
506 ULARGE_INTEGER cb, DWORD dwLockType)
508 ok(0, "unexpected call\n");
509 return E_NOTIMPL;
512 static HRESULT WINAPI Stream_UnlockRegion(IStream *iface,
513 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
515 ok(0, "unexpected call\n");
516 return E_NOTIMPL;
519 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
520 DWORD dwStatFlag)
522 ok(0, "unexpected call\n");
523 return E_NOTIMPL;
526 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
528 ok(0, "unexpected call\n");
529 return E_NOTIMPL;
532 static const IStreamVtbl StreamVtbl = {
533 Stream_QueryInterface,
534 Stream_AddRef,
535 Stream_Release,
536 Stream_Read,
537 Stream_Write,
538 Stream_Seek,
539 Stream_SetSize,
540 Stream_CopyTo,
541 Stream_Commit,
542 Stream_Revert,
543 Stream_LockRegion,
544 Stream_UnlockRegion,
545 Stream_Stat,
546 Stream_Clone
549 static IStream Stream = { &StreamVtbl };
551 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
553 return QueryInterface(riid, ppv);
556 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
558 return 2;
561 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
563 return 1;
566 static void call_continue(PROTOCOLDATA *protocol_data)
568 HRESULT hres;
570 if(state == STATE_CONNECTING) {
571 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
572 if (http_is_first){
573 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
574 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
576 CLEAR_CALLED(ReportProgress_CONNECTING);
578 if(tested_protocol == FTP_TEST)
579 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
580 else if (tested_protocol != HTTPS_TEST)
581 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
582 if(test_redirect)
583 CHECK_CALLED(ReportProgress_REDIRECTING);
584 state = test_async_req ? STATE_SENDINGREQUEST : STATE_STARTDOWNLOADING;
587 switch(state) {
588 case STATE_SENDINGREQUEST:
589 SET_EXPECT(Stream_Read);
590 SET_EXPECT(ReportProgress_SENDINGREQUEST);
591 break;
592 case STATE_STARTDOWNLOADING:
593 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
594 SET_EXPECT(OnResponse);
595 if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file)
596 SET_EXPECT(ReportProgress_ACCEPTRANGES);
597 SET_EXPECT(ReportProgress_ENCODING);
598 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
599 if(bindf & BINDF_NEEDFILE)
600 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
602 default:
603 break;
606 if(state != STATE_SENDINGREQUEST)
607 SET_EXPECT(ReportData);
608 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
609 ok(hres == S_OK, "Continue failed: %08x\n", hres);
610 if(tested_protocol == FTP_TEST || security_problem)
611 CLEAR_CALLED(ReportData);
612 else if(state != STATE_SENDINGREQUEST)
613 CHECK_CALLED(ReportData);
615 switch(state) {
616 case STATE_SENDINGREQUEST:
617 CHECK_CALLED(Stream_Read);
618 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
619 state = STATE_STARTDOWNLOADING;
620 break;
621 case STATE_STARTDOWNLOADING:
622 if (! security_problem)
624 state = STATE_DOWNLOADING;
625 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
626 CHECK_CALLED(OnResponse);
627 if(tested_protocol == HTTPS_TEST || empty_file)
628 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
629 else if(test_redirect || test_abort)
630 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
631 CLEAR_CALLED(ReportProgress_ENCODING);
632 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
633 if(bindf & BINDF_NEEDFILE)
634 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
637 else
639 security_problem = FALSE;
640 SET_EXPECT(ReportProgress_CONNECTING);
642 default:
643 break;
647 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
649 if(tested_protocol == FTP_TEST)
650 CHECK_EXPECT2(Switch);
651 else
652 CHECK_EXPECT(Switch);
654 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
655 if(binding_test) {
656 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
657 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
658 pProtocolData->grfFlags, protocoldata.grfFlags );
659 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
660 pProtocolData->dwState, protocoldata.dwState );
661 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
662 pProtocolData->pData, protocoldata.pData );
663 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
664 pProtocolData->cbData, protocoldata.cbData );
667 pdata = pProtocolData;
669 if(binding_test) {
670 SetEvent(event_complete);
671 WaitForSingleObject(event_complete2, INFINITE);
672 return S_OK;
673 }if(direct_read) {
674 continue_protdata = *pProtocolData;
675 SetEvent(event_continue);
676 WaitForSingleObject(event_continue_done, INFINITE);
677 }else {
678 call_continue(pProtocolData);
679 SetEvent(event_complete);
682 return S_OK;
685 static const char *status_names[] =
687 "0",
688 "FINDINGRESOURCE",
689 "CONNECTING",
690 "REDIRECTING",
691 "BEGINDOWNLOADDATA",
692 "DOWNLOADINGDATA",
693 "ENDDOWNLOADDATA",
694 "BEGINDOWNLOADCOMPONENTS",
695 "INSTALLINGCOMPONENTS",
696 "ENDDOWNLOADCOMPONENTS",
697 "USINGCACHEDCOPY",
698 "SENDINGREQUEST",
699 "CLASSIDAVAILABLE",
700 "MIMETYPEAVAILABLE",
701 "CACHEFILENAMEAVAILABLE",
702 "BEGINSYNCOPERATION",
703 "ENDSYNCOPERATION",
704 "BEGINUPLOADDATA",
705 "UPLOADINGDATA",
706 "ENDUPLOADINGDATA",
707 "PROTOCOLCLASSID",
708 "ENCODING",
709 "VERIFIEDMIMETYPEAVAILABLE",
710 "CLASSINSTALLLOCATION",
711 "DECODING",
712 "LOADINGMIMEHANDLER",
713 "CONTENTDISPOSITIONATTACH",
714 "FILTERREPORTMIMETYPE",
715 "CLSIDCANINSTANTIATE",
716 "IUNKNOWNAVAILABLE",
717 "DIRECTBIND",
718 "RAWMIMETYPE",
719 "PROXYDETECTING",
720 "ACCEPTRANGES",
721 "COOKIE_SENT",
722 "COMPACT_POLICY_RECEIVED",
723 "COOKIE_SUPPRESSED",
724 "COOKIE_STATE_UNKNOWN",
725 "COOKIE_STATE_ACCEPT",
726 "COOKIE_STATE_REJECT",
727 "COOKIE_STATE_PROMPT",
728 "COOKIE_STATE_LEASH",
729 "COOKIE_STATE_DOWNGRADE",
730 "POLICY_HREF",
731 "P3P_HEADER",
732 "SESSION_COOKIE_RECEIVED",
733 "PERSISTENT_COOKIE_RECEIVED",
734 "SESSION_COOKIES_ALLOWED",
735 "CACHECONTROL",
736 "CONTENTDISPOSITIONFILENAME",
737 "MIMETEXTPLAINMISMATCH",
738 "PUBLISHERAVAILABLE",
739 "DISPLAYNAMEAVAILABLE"
742 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
743 LPCWSTR szStatusText)
745 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
746 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
747 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
749 if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0]))
750 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
751 else
752 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
754 switch(ulStatusCode) {
755 case BINDSTATUS_MIMETYPEAVAILABLE:
756 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
757 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
758 if(!short_read || !direct_read)
759 CHECK_CALLED(Read); /* set in Continue */
760 else if(short_read)
761 CHECK_CALLED(Read2); /* set in Read */
763 ok(szStatusText != NULL, "szStatusText == NULL\n");
764 if(szStatusText) {
765 if(tested_protocol == BIND_TEST)
766 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
767 else if (http_post_test)
768 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
769 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
770 "szStatusText != text/plain\n");
771 else if(empty_file)
772 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
773 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
774 && tested_protocol==HTTP_TEST && !short_read)
775 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
776 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
777 "szStatusText != image/gif\n");
778 else if(!mimefilter_test)
779 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
780 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
781 "szStatusText != text/html\n");
783 break;
784 case BINDSTATUS_DIRECTBIND:
785 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
786 ok(szStatusText == NULL, "szStatusText != NULL\n");
787 break;
788 case BINDSTATUS_RAWMIMETYPE:
789 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
790 ok(szStatusText != NULL, "szStatusText == NULL\n");
791 if(szStatusText)
792 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
793 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
794 "szStatusText != text/html\n");
795 break;
796 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
797 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
798 ok(szStatusText != NULL, "szStatusText == NULL\n");
799 if(szStatusText) {
800 if(binding_test)
801 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
802 else if(tested_protocol == FILE_TEST)
803 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
804 else
805 ok(szStatusText != NULL, "szStatusText == NULL\n");
807 break;
808 case BINDSTATUS_FINDINGRESOURCE:
809 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
810 ok(szStatusText != NULL, "szStatusText == NULL\n");
811 break;
812 case BINDSTATUS_CONNECTING:
813 CHECK_EXPECT2(ReportProgress_CONNECTING);
814 ok(szStatusText != NULL, "szStatusText == NULL\n");
815 break;
816 case BINDSTATUS_SENDINGREQUEST:
817 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
818 if(tested_protocol == FILE_TEST || tested_protocol == ITS_TEST) {
819 ok(szStatusText != NULL, "szStatusText == NULL\n");
820 if(szStatusText)
821 ok(!*szStatusText, "wrong szStatusText\n");
823 break;
824 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
825 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
826 ok(szStatusText != NULL, "szStatusText == NULL\n");
827 if(szStatusText)
828 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
829 break;
830 case BINDSTATUS_PROTOCOLCLASSID:
831 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
832 ok(szStatusText != NULL, "szStatusText == NULL\n");
833 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
834 break;
835 case BINDSTATUS_COOKIE_SENT:
836 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
837 ok(szStatusText == NULL, "szStatusText != NULL\n");
838 break;
839 case BINDSTATUS_REDIRECTING:
840 CHECK_EXPECT(ReportProgress_REDIRECTING);
841 if(test_redirect)
842 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
843 else
844 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
845 break;
846 case BINDSTATUS_ENCODING:
847 CHECK_EXPECT(ReportProgress_ENCODING);
848 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
849 break;
850 case BINDSTATUS_ACCEPTRANGES:
851 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
852 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
853 break;
854 case BINDSTATUS_PROXYDETECTING:
855 if(!called_ReportProgress_PROXYDETECTING)
856 SET_EXPECT(ReportProgress_CONNECTING);
857 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
858 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
859 break;
860 case BINDSTATUS_LOADINGMIMEHANDLER:
861 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
862 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
863 break;
864 case BINDSTATUS_DECODING:
865 CHECK_EXPECT(ReportProgress_DECODING);
866 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
867 break;
868 default:
869 ok(0, "Unexpected status %d\n", ulStatusCode);
872 return S_OK;
875 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
876 ULONG ulProgress, ULONG ulProgressMax)
878 HRESULT hres;
880 static int rec_depth;
881 rec_depth++;
883 if(!mimefilter_test && (tested_protocol == FILE_TEST || tested_protocol == ITS_TEST)) {
884 CHECK_EXPECT2(ReportData);
886 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
887 ulProgress, ulProgressMax);
888 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
889 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
890 if(tested_protocol == FILE_TEST)
891 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
892 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
893 "grcfBSCF = %08x\n", grfBSCF);
894 else
895 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
896 }else if(direct_read) {
897 BYTE buf[14096];
898 ULONG read;
900 if(!read_report_data && rec_depth == 1) {
901 BOOL reported_all_data = called_ReportData2;
903 CHECK_EXPECT2(ReportData);
905 if(short_read) {
906 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
907 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
908 "grcfBSCF = %08x\n", grfBSCF);
909 CHECK_CALLED(Read); /* Set in Continue */
910 first_data_notif = FALSE;
911 }else if(first_data_notif) {
912 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
913 first_data_notif = FALSE;
914 }else if(reported_all_data) {
915 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
916 "grcfBSCF = %08x\n", grfBSCF);
917 }else if(!direct_read) {
918 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
921 do {
922 read = 0;
923 if(emulate_prot)
924 SET_EXPECT(Read);
925 else
926 SET_EXPECT(ReportData2);
927 SET_EXPECT(ReportResult);
928 if(!emulate_prot)
929 SET_EXPECT(Switch);
930 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
931 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
932 if(hres == S_OK)
933 ok(read, "read == 0\n");
934 if(reported_all_data)
935 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
936 if(!emulate_prot && hres != E_PENDING)
937 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
938 if(emulate_prot)
939 CHECK_CALLED(Read);
940 if(!reported_all_data && called_ReportData2) {
941 if(!emulate_prot)
942 CHECK_CALLED(ReportData2);
943 CHECK_CALLED(ReportResult);
944 reported_all_data = TRUE;
945 }else {
946 if(!emulate_prot)
947 CHECK_NOT_CALLED(ReportData2);
948 CHECK_NOT_CALLED(ReportResult);
950 }while(hres == S_OK);
951 if(hres == S_FALSE)
952 wait_for_switch = FALSE;
953 }else {
954 CHECK_EXPECT(ReportData2);
956 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
958 read = 0xdeadbeef;
959 if(emulate_prot)
960 SET_EXPECT(Read2);
961 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
962 if(emulate_prot)
963 CHECK_CALLED(Read2);
964 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
965 ok(!read, "read = %d\n", read);
967 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST
968 || tested_protocol == FTP_TEST)) {
969 if(empty_file)
970 CHECK_EXPECT2(ReportData);
971 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
972 CHECK_EXPECT(ReportData);
973 else if (http_post_test)
974 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
976 if(empty_file) {
977 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
978 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
979 }else {
980 ok(ulProgress, "ulProgress == 0\n");
983 if(empty_file) {
984 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
985 "grcfBSCF = %08x\n", grfBSCF);
986 first_data_notif = FALSE;
987 }else if(first_data_notif) {
988 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
989 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
990 "grcfBSCF = %08x\n", grfBSCF);
991 first_data_notif = FALSE;
992 } else {
993 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
994 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
995 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
996 "grcfBSCF = %08x\n", grfBSCF);
999 if(!(bindf & BINDF_FROMURLMON) &&
1000 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1001 if(state == STATE_CONNECTING) {
1002 state = STATE_DOWNLOADING;
1003 if(http_is_first) {
1004 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1005 CHECK_CALLED(ReportProgress_CONNECTING);
1007 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1008 CHECK_CALLED(OnResponse);
1009 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1011 SetEvent(event_complete);
1013 }else if(!read_report_data) {
1014 BYTE buf[1000];
1015 ULONG read;
1016 HRESULT hres;
1018 CHECK_EXPECT(ReportData);
1020 if(tested_protocol != BIND_TEST) {
1021 do {
1022 if(mimefilter_test)
1023 SET_EXPECT(MimeFilter_Read);
1024 else if(rec_depth > 1)
1025 SET_EXPECT(Read2);
1026 else
1027 SET_EXPECT(Read);
1028 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1029 if(mimefilter_test)
1030 CHECK_CALLED(MimeFilter_Read);
1031 else if(rec_depth > 1)
1032 CHECK_CALLED(Read2);
1033 else
1034 CHECK_CALLED(Read);
1035 }while(hres == S_OK);
1039 rec_depth--;
1040 return S_OK;
1043 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1044 DWORD dwError, LPCWSTR szResult)
1046 CHECK_EXPECT(ReportResult);
1048 if(tested_protocol == FTP_TEST)
1049 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1050 else
1051 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1052 hrResult, expect_hrResult);
1053 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort)
1054 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1055 else
1056 ok(dwError != ERROR_SUCCESS ||
1057 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1058 "dwError == ERROR_SUCCESS\n");
1059 ok(!szResult, "szResult != NULL\n");
1061 if(direct_read)
1062 SET_EXPECT(ReportData); /* checked after main loop */
1064 return S_OK;
1067 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1068 ProtocolSink_QueryInterface,
1069 ProtocolSink_AddRef,
1070 ProtocolSink_Release,
1071 ProtocolSink_Switch,
1072 ProtocolSink_ReportProgress,
1073 ProtocolSink_ReportData,
1074 ProtocolSink_ReportResult
1077 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
1079 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
1081 ok(0, "unexpected call\n");
1082 return E_NOTIMPL;
1085 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1087 return 2;
1090 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1092 return 1;
1095 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1097 HRESULT hres;
1099 CHECK_EXPECT(MimeFilter_Switch);
1101 SET_EXPECT(Switch);
1102 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1103 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1104 CHECK_CALLED(Switch);
1106 return S_OK;
1109 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1110 LPCWSTR szStatusText)
1112 switch(ulStatusCode) {
1113 case BINDSTATUS_LOADINGMIMEHANDLER:
1115 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1116 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1117 * ProtocolSink_ReportProgress to workaround it.
1119 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1120 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1121 break;
1122 default:
1123 ok(0, "Unexpected status code %d\n", ulStatusCode);
1126 return S_OK;
1129 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1130 ULONG ulProgress, ULONG ulProgressMax)
1132 DWORD read = 0;
1133 BYTE buf[8192];
1134 HRESULT hres;
1135 BOOL report_mime = FALSE;
1137 CHECK_EXPECT(MimeFilter_ReportData);
1139 if(!filter_state && !no_mime) {
1140 SET_EXPECT(Read);
1141 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1142 if(tested_protocol == HTTP_TEST)
1143 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1144 else
1145 ok(hres == S_OK, "Read failed: %08x\n", hres);
1146 CHECK_CALLED(Read);
1148 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1149 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1150 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1151 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1153 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1154 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1155 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1156 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1158 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1161 if(no_mime && prot_read<200) {
1162 SET_EXPECT(Read);
1163 }else if(no_mime && prot_read<300) {
1164 report_mime = TRUE;
1165 SET_EXPECT(Read);
1166 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1167 SET_EXPECT(ReportData);
1168 }else if(!read_report_data) {
1169 SET_EXPECT(ReportData);
1171 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1172 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1173 if(no_mime && prot_read<=200) {
1174 CHECK_CALLED(Read);
1175 }else if(report_mime) {
1176 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1177 CHECK_CALLED(ReportData);
1178 }else if(!read_report_data) {
1179 CHECK_CALLED(ReportData);
1182 if(!filter_state)
1183 filter_state = 1;
1185 return S_OK;
1188 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1189 DWORD dwError, LPCWSTR szResult)
1191 HRESULT hres;
1193 CHECK_EXPECT(MimeFilter_ReportResult);
1195 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1196 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1197 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1199 SET_EXPECT(ReportResult);
1200 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1201 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1202 CHECK_CALLED(ReportResult);
1204 return S_OK;
1207 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1208 MimeProtocolSink_QueryInterface,
1209 MimeProtocolSink_AddRef,
1210 MimeProtocolSink_Release,
1211 MimeProtocolSink_Switch,
1212 MimeProtocolSink_ReportProgress,
1213 MimeProtocolSink_ReportData,
1214 MimeProtocolSink_ReportResult
1217 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1219 static HRESULT QueryInterface(REFIID riid, void **ppv)
1221 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1223 *ppv = NULL;
1225 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1226 *ppv = &protocol_sink;
1227 if(IsEqualGUID(&IID_IServiceProvider, riid))
1228 *ppv = &service_provider;
1229 if(IsEqualGUID(&IID_IUriContainer, riid))
1230 return E_NOINTERFACE; /* TODO */
1232 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1233 if(IsEqualGUID(&IID_undocumented, riid))
1234 return E_NOINTERFACE;
1236 if(*ppv)
1237 return S_OK;
1239 ok(0, "unexpected call %s\n", debugstr_guid(riid));
1240 return E_NOINTERFACE;
1243 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1245 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1246 *ppv = iface;
1247 return S_OK;
1249 return E_NOINTERFACE;
1252 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1254 return 2;
1257 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1259 return 1;
1262 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1264 DWORD cbSize;
1266 CHECK_EXPECT(GetBindInfo);
1268 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1269 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1270 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1272 *grfBINDF = bindf;
1273 if(binding_test)
1274 *grfBINDF |= BINDF_FROMURLMON;
1275 cbSize = pbindinfo->cbSize;
1276 memset(pbindinfo, 0, cbSize);
1277 pbindinfo->cbSize = cbSize;
1279 if(http_post_test)
1281 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1282 pbindinfo->dwBindVerb = BINDVERB_POST;
1283 pbindinfo->stgmedData.tymed = http_post_test;
1285 if(http_post_test == TYMED_HGLOBAL) {
1286 HGLOBAL data;
1288 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1289 data = GlobalAlloc(GPTR, sizeof(post_data));
1290 memcpy(data, post_data, sizeof(post_data));
1291 U(pbindinfo->stgmedData).hGlobal = data;
1292 }else {
1293 IStream *post_stream;
1294 HGLOBAL data;
1295 HRESULT hres;
1297 if(0) {
1298 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1299 data = GlobalAlloc(GPTR, sizeof(post_data));
1300 memcpy(data, post_data, sizeof(post_data));
1301 U(pbindinfo->stgmedData).hGlobal = data;
1303 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1304 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1306 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1308 U(pbindinfo->stgmedData).pstm = &Stream;
1312 return S_OK;
1315 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1316 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1318 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1319 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1321 switch(ulStringType) {
1322 case BINDSTRING_ACCEPT_MIMES:
1323 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1324 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1325 if(pcElFetched) {
1326 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1327 *pcElFetched = 1;
1329 if(ppwzStr) {
1330 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1331 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1333 return S_OK;
1334 case BINDSTRING_USER_AGENT:
1335 CHECK_EXPECT(GetBindString_USER_AGENT);
1336 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1337 if(pcElFetched) {
1338 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1339 *pcElFetched = 1;
1341 if(ppwzStr) {
1342 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1343 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1345 return S_OK;
1346 case BINDSTRING_POST_COOKIE:
1347 CHECK_EXPECT(GetBindString_POST_COOKIE);
1348 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1349 if(pcElFetched)
1350 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1351 return S_OK;
1352 case BINDSTRING_URL: {
1353 DWORD size;
1355 CHECK_EXPECT(GetBindString_URL);
1356 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1357 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1358 *pcElFetched = 1;
1360 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1361 *ppwzStr = CoTaskMemAlloc(size);
1362 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1363 return S_OK;
1365 default:
1366 ok(0, "unexpected call\n");
1369 return E_NOTIMPL;
1372 static IInternetBindInfoVtbl bind_info_vtbl = {
1373 BindInfo_QueryInterface,
1374 BindInfo_AddRef,
1375 BindInfo_Release,
1376 BindInfo_GetBindInfo,
1377 BindInfo_GetBindString
1380 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1382 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1383 REFIID riid, void **ppv)
1385 ok(0, "unexpected call\n");
1386 return E_NOINTERFACE;
1389 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1391 return 2;
1394 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1396 return 1;
1399 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1401 CHECK_EXPECT(SetPriority);
1402 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1403 return S_OK;
1406 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1408 ok(0, "unexpected call\n");
1409 return E_NOTIMPL;
1413 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1414 InternetPriority_QueryInterface,
1415 InternetPriority_AddRef,
1416 InternetPriority_Release,
1417 InternetPriority_SetPriority,
1418 InternetPriority_GetPriority
1421 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1423 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1425 return 2;
1428 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1430 return 1;
1433 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1434 DWORD dwOptions)
1436 HRESULT hres;
1438 CHECK_EXPECT(Abort);
1440 SET_EXPECT(ReportResult);
1441 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1442 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1443 CHECK_CALLED(ReportResult);
1445 return S_OK;
1448 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1450 ok(0, "unexpected call\n");
1451 return E_NOTIMPL;
1454 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1456 ok(0, "unexpected call\n");
1457 return E_NOTIMPL;
1460 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1461 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1463 ok(0, "unexpected call\n");
1464 return E_NOTIMPL;
1467 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1469 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1470 *ppv = iface;
1471 return S_OK;
1474 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1475 if(impl_protex) {
1476 *ppv = iface;
1477 return S_OK;
1479 *ppv = NULL;
1480 return E_NOINTERFACE;
1483 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1484 *ppv = &InternetPriority;
1485 return S_OK;
1488 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1489 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1490 *ppv = NULL;
1491 return E_NOINTERFACE;
1494 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1495 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1496 *ppv = NULL;
1497 return E_NOINTERFACE;
1500 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1501 *ppv = NULL;
1502 return E_NOINTERFACE;
1505 static DWORD WINAPI thread_proc(PVOID arg)
1507 HRESULT hres;
1509 memset(&protocoldata, -1, sizeof(protocoldata));
1511 prot_state = 0;
1513 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1514 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1515 BINDSTATUS_FINDINGRESOURCE, hostW);
1516 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1517 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1519 SET_EXPECT(ReportProgress_CONNECTING);
1520 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1521 BINDSTATUS_CONNECTING, winehq_ipW);
1522 CHECK_CALLED(ReportProgress_CONNECTING);
1523 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1525 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1526 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1527 BINDSTATUS_SENDINGREQUEST, NULL);
1528 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1529 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1531 prot_state = 1;
1532 SET_EXPECT(Switch);
1533 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1534 CHECK_CALLED(Switch);
1535 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1537 if(!short_read) {
1538 prot_state = 2;
1539 if(mimefilter_test)
1540 SET_EXPECT(MimeFilter_Switch);
1541 else
1542 SET_EXPECT(Switch);
1543 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1544 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1545 if(mimefilter_test)
1546 CHECK_CALLED(MimeFilter_Switch);
1547 else
1548 CHECK_CALLED(Switch);
1550 if(test_abort) {
1551 SetEvent(event_complete);
1552 return 0;
1555 prot_state = 2;
1556 if(mimefilter_test)
1557 SET_EXPECT(MimeFilter_Switch);
1558 else
1559 SET_EXPECT(Switch);
1560 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1561 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1562 if(mimefilter_test)
1563 CHECK_CALLED(MimeFilter_Switch);
1564 else
1565 CHECK_CALLED(Switch);
1567 prot_state = 3;
1568 if(mimefilter_test)
1569 SET_EXPECT(MimeFilter_Switch);
1570 else
1571 SET_EXPECT(Switch);
1572 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1573 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1574 if(mimefilter_test)
1575 CHECK_CALLED(MimeFilter_Switch);
1576 else
1577 CHECK_CALLED(Switch);
1580 SetEvent(event_complete);
1582 return 0;
1585 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1587 BINDINFO bindinfo, exp_bindinfo;
1588 DWORD cbindf = 0;
1589 HRESULT hres;
1591 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1592 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1593 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1594 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1595 ok(!pi, "pi = %x\n", pi);
1597 if(binding_test)
1598 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1600 memset(&bindinfo, 0, sizeof(bindinfo));
1601 bindinfo.cbSize = sizeof(bindinfo);
1602 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1603 SET_EXPECT(GetBindInfo);
1604 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1605 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1606 CHECK_CALLED(GetBindInfo);
1607 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1608 cbindf, (bindf|BINDF_FROMURLMON));
1609 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1610 pReleaseBindInfo(&bindinfo);
1612 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1613 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1614 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1615 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1617 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1618 IServiceProvider *service_provider;
1619 IHttpNegotiate *http_negotiate;
1620 IHttpNegotiate2 *http_negotiate2;
1621 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1622 LPWSTR additional_headers = NULL;
1623 BYTE sec_id[100];
1624 DWORD fetched = 0, size = 100;
1625 DWORD tid;
1627 SET_EXPECT(GetBindString_USER_AGENT);
1628 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1629 &ua, 1, &fetched);
1630 CHECK_CALLED(GetBindString_USER_AGENT);
1631 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1632 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1633 ok(ua != NULL, "ua = %p\n", ua);
1634 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1635 CoTaskMemFree(ua);
1637 fetched = 256;
1638 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1639 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1640 accept_mimes, 256, &fetched);
1641 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1643 ok(hres == S_OK,
1644 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1645 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1646 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1647 CoTaskMemFree(accept_mimes[0]);
1649 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1650 (void**)&service_provider);
1651 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1653 SET_EXPECT(QueryService_HttpNegotiate);
1654 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1655 &IID_IHttpNegotiate, (void**)&http_negotiate);
1656 CHECK_CALLED(QueryService_HttpNegotiate);
1657 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1659 SET_EXPECT(BeginningTransaction);
1660 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1661 NULL, 0, &additional_headers);
1662 CHECK_CALLED(BeginningTransaction);
1663 IHttpNegotiate_Release(http_negotiate);
1664 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1665 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1667 SET_EXPECT(QueryService_HttpNegotiate);
1668 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1669 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1670 CHECK_CALLED(QueryService_HttpNegotiate);
1671 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1673 size = 512;
1674 SET_EXPECT(GetRootSecurityId);
1675 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1676 CHECK_CALLED(GetRootSecurityId);
1677 IHttpNegotiate2_Release(http_negotiate2);
1678 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1679 ok(size == 13, "size=%d\n", size);
1681 IServiceProvider_Release(service_provider);
1683 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1684 return;
1687 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1688 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1689 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1690 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1691 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1693 if(mimefilter_test) {
1694 SET_EXPECT(MimeFilter_CreateInstance);
1695 SET_EXPECT(MimeFilter_Start);
1696 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1698 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1699 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1700 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1701 ok(hres == S_OK,
1702 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1703 if(mimefilter_test) {
1704 CHECK_CALLED(MimeFilter_CreateInstance);
1705 CHECK_CALLED(MimeFilter_Start);
1706 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1707 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1708 }else {
1709 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1712 if(mimefilter_test)
1713 SET_EXPECT(MimeFilter_ReportData);
1714 else
1715 SET_EXPECT(ReportData);
1716 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1717 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1718 13, 13);
1719 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1720 if(mimefilter_test)
1721 CHECK_CALLED(MimeFilter_ReportData);
1722 else
1723 CHECK_CALLED(ReportData);
1725 if(tested_protocol == ITS_TEST) {
1726 SET_EXPECT(ReportData);
1727 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1728 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1729 CHECK_CALLED(ReportData);
1732 if(tested_protocol == BIND_TEST) {
1733 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1734 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1737 if(mimefilter_test)
1738 SET_EXPECT(MimeFilter_ReportResult);
1739 else
1740 SET_EXPECT(ReportResult);
1741 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1742 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1743 if(mimefilter_test)
1744 CHECK_CALLED(MimeFilter_ReportResult);
1745 else
1746 CHECK_CALLED(ReportResult);
1749 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1750 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1751 DWORD grfPI, HANDLE_PTR dwReserved)
1753 CHECK_EXPECT(Start);
1755 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1756 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1757 return S_OK;
1760 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1761 PROTOCOLDATA *pProtocolData)
1763 DWORD bscf = 0, pr;
1764 HRESULT hres;
1766 CHECK_EXPECT(Continue);
1768 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1769 if(!pProtocolData || tested_protocol == BIND_TEST)
1770 return S_OK;
1771 if(binding_test) {
1772 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1773 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1774 pProtocolData->grfFlags, protocoldata.grfFlags );
1775 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1776 pProtocolData->dwState, protocoldata.dwState );
1777 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1778 pProtocolData->pData, protocoldata.pData );
1779 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1780 pProtocolData->cbData, protocoldata.cbData );
1783 switch(prot_state) {
1784 case 1: {
1785 IServiceProvider *service_provider;
1786 IHttpNegotiate *http_negotiate;
1787 static WCHAR header[] = {'?',0};
1789 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1790 (void**)&service_provider);
1791 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1793 SET_EXPECT(QueryService_HttpNegotiate);
1794 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1795 &IID_IHttpNegotiate, (void**)&http_negotiate);
1796 IServiceProvider_Release(service_provider);
1797 CHECK_CALLED(QueryService_HttpNegotiate);
1798 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1800 SET_EXPECT(OnResponse);
1801 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1802 IHttpNegotiate_Release(http_negotiate);
1803 CHECK_CALLED(OnResponse);
1804 IHttpNegotiate_Release(http_negotiate);
1805 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1807 if(mimefilter_test) {
1808 SET_EXPECT(MimeFilter_CreateInstance);
1809 SET_EXPECT(MimeFilter_Start);
1810 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1811 }else if(!(pi & PI_MIMEVERIFICATION)) {
1812 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1814 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1815 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1816 if(mimefilter_test) {
1817 CHECK_CALLED(MimeFilter_CreateInstance);
1818 CHECK_CALLED(MimeFilter_Start);
1819 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1820 }else if(!(pi & PI_MIMEVERIFICATION)) {
1821 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1823 ok(hres == S_OK,
1824 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1826 bscf |= BSCF_FIRSTDATANOTIFICATION;
1827 break;
1829 case 2:
1830 case 3:
1831 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1832 break;
1835 pr = prot_read;
1836 if(mimefilter_test)
1837 SET_EXPECT(MimeFilter_ReportData);
1838 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1839 if(pr < 200)
1840 SET_EXPECT(Read); /* checked in ReportData for short_read */
1841 if(pr == 200) {
1842 if(!mimefilter_test)
1843 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1844 SET_EXPECT(GetBindInfo);
1845 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1847 if(pr >= 200)
1848 SET_EXPECT(ReportData);
1849 }else {
1850 SET_EXPECT(ReportData);
1853 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1854 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1856 if(mimefilter_test) {
1857 SET_EXPECT(MimeFilter_ReportData);
1858 }else if(pi & PI_MIMEVERIFICATION) {
1859 if(!short_read && pr < 200)
1860 CHECK_CALLED(Read);
1861 if(pr == 200) {
1862 CLEAR_CALLED(GetBindInfo); /* IE9 */
1863 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1865 }else {
1866 CHECK_CALLED(ReportData);
1869 if(prot_state == 3)
1870 prot_state = 4;
1872 return S_OK;
1875 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1877 CHECK_EXPECT(Terminate);
1878 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1879 return S_OK;
1882 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1883 ULONG cb, ULONG *pcbRead)
1885 if(read_report_data)
1886 CHECK_EXPECT2(Read2);
1888 if(mimefilter_test || short_read) {
1889 if(!read_report_data)
1890 CHECK_EXPECT2(Read);
1891 }else if((pi & PI_MIMEVERIFICATION)) {
1892 if(!read_report_data)
1893 CHECK_EXPECT2(Read);
1895 if(prot_read < 300) {
1896 ok(pv != expect_pv, "pv == expect_pv\n");
1897 if(prot_read < 300)
1898 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1899 else
1900 ok(cb == 700, "cb=%d\n", cb);
1901 }else {
1902 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1904 }else {
1905 if(!read_report_data)
1906 CHECK_EXPECT(Read);
1908 ok(pv == expect_pv, "pv != expect_pv\n");
1909 ok(cb == 1000, "cb=%d\n", cb);
1910 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1912 ok(pcbRead != NULL, "pcbRead == NULL\n");
1914 if(prot_state == 3 || (short_read && prot_state != 4)) {
1915 HRESULT hres;
1917 prot_state = 4;
1918 if(short_read) {
1919 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1920 SET_EXPECT(GetBindInfo);
1921 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1923 if(mimefilter_test)
1924 SET_EXPECT(MimeFilter_ReportData);
1925 else if(direct_read)
1926 SET_EXPECT(ReportData2);
1927 read_report_data++;
1928 hres = IInternetProtocolSink_ReportData(binding_sink,
1929 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1930 read_report_data--;
1931 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1932 if(short_read) {
1933 CLEAR_CALLED(GetBindInfo); /* IE9 */
1934 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1936 if(mimefilter_test)
1937 CHECK_CALLED(MimeFilter_ReportData);
1938 else if(direct_read)
1939 CHECK_CALLED(ReportData2);
1941 if(mimefilter_test)
1942 SET_EXPECT(MimeFilter_ReportResult);
1943 else
1944 SET_EXPECT(ReportResult);
1945 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1946 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1947 if(mimefilter_test)
1948 CHECK_CALLED(MimeFilter_ReportResult);
1949 else
1950 CHECK_CALLED(ReportResult);
1952 if(cb > 100)
1953 cb = 100;
1954 memset(pv, 'x', cb);
1955 if(cb>6)
1956 memcpy(pv, "gif87a", 6);
1957 prot_read += *pcbRead = cb;
1958 return S_OK;
1959 }if(prot_state == 4) {
1960 *pcbRead = 0;
1961 return S_FALSE;
1964 if((async_read_pending = !async_read_pending)) {
1965 *pcbRead = 0;
1966 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
1969 if(cb > 100)
1970 cb = 100;
1971 memset(pv, 'x', cb);
1972 if(cb>6)
1973 memcpy(pv, "gif87a", 6);
1974 prot_read += *pcbRead = cb;
1975 return S_OK;
1978 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
1980 CHECK_EXPECT(LockRequest);
1981 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
1982 return S_OK;
1985 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
1987 CHECK_EXPECT(UnlockRequest);
1988 return S_OK;
1991 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
1992 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1993 DWORD grfPI, HANDLE *dwReserved)
1995 CHECK_EXPECT(StartEx);
1996 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
1997 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1998 return S_OK;
2001 static const IInternetProtocolExVtbl ProtocolVtbl = {
2002 ProtocolEmul_QueryInterface,
2003 Protocol_AddRef,
2004 Protocol_Release,
2005 ProtocolEmul_Start,
2006 ProtocolEmul_Continue,
2007 Protocol_Abort,
2008 ProtocolEmul_Terminate,
2009 Protocol_Suspend,
2010 Protocol_Resume,
2011 ProtocolEmul_Read,
2012 Protocol_Seek,
2013 ProtocolEmul_LockRequest,
2014 ProtocolEmul_UnlockRequest,
2015 ProtocolEmul_StartEx
2018 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2020 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2022 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2023 *ppv = iface;
2024 return S_OK;
2027 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2028 *ppv = &mime_protocol_sink;
2029 return S_OK;
2032 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2033 *ppv = NULL;
2034 return E_NOINTERFACE;
2037 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2038 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2039 DWORD grfPI, HANDLE_PTR dwReserved)
2041 PROTOCOLFILTERDATA *data;
2042 LPOLESTR url_str = NULL;
2043 DWORD fetched = 0;
2044 BINDINFO bindinfo;
2045 DWORD cbindf = 0;
2046 HRESULT hres;
2048 CHECK_EXPECT(MimeFilter_Start);
2050 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2051 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2052 ok(dwReserved, "dwReserved == 0\n");
2053 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2054 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2056 if(binding_test) {
2057 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2058 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2059 }else {
2060 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2061 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2064 data = (void*)dwReserved;
2065 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2066 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2067 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2068 ok(!data->pUnk, "data->pUnk != NULL\n");
2069 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2070 if(binding_test) {
2071 IInternetProtocolSink *prot_sink;
2073 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2074 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2075 IInternetProtocolSink_Release(prot_sink);
2077 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2079 filtered_protocol = data->pProtocol;
2080 IInternetProtocol_AddRef(filtered_protocol);
2081 }else {
2082 IInternetProtocol *prot;
2084 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2085 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2086 IInternetProtocol_Release(prot);
2088 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2091 filtered_sink = pOIProtSink;
2093 SET_EXPECT(ReportProgress_DECODING);
2094 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2095 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2096 CHECK_CALLED(ReportProgress_DECODING);
2098 SET_EXPECT(GetBindInfo);
2099 memset(&bindinfo, 0, sizeof(bindinfo));
2100 bindinfo.cbSize = sizeof(bindinfo);
2101 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2102 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2103 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2104 CHECK_CALLED(GetBindInfo);
2106 SET_EXPECT(GetBindString_URL);
2107 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2108 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2109 ok(fetched == 1, "fetched = %d\n", fetched);
2110 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2111 CoTaskMemFree(url_str);
2112 CHECK_CALLED(GetBindString_URL);
2114 return S_OK;
2117 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2118 PROTOCOLDATA *pProtocolData)
2120 CHECK_EXPECT(MimeFilter_Continue);
2121 return E_NOTIMPL;
2124 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2126 HRESULT hres;
2128 CHECK_EXPECT(MimeFilter_Terminate);
2130 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2132 SET_EXPECT(Terminate);
2133 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2134 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2135 CHECK_CALLED(Terminate);
2137 return S_OK;
2140 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2141 ULONG cb, ULONG *pcbRead)
2143 BYTE buf[2096];
2144 DWORD read = 0;
2145 HRESULT hres;
2147 CHECK_EXPECT(MimeFilter_Read);
2149 ok(pv != NULL, "pv == NULL\n");
2150 ok(cb != 0, "cb == 0\n");
2151 ok(pcbRead != NULL, "pcbRead == NULL\n");
2153 if(read_report_data)
2154 SET_EXPECT(Read2);
2155 else
2156 SET_EXPECT(Read);
2157 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2158 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2159 if(read_report_data)
2160 CHECK_CALLED(Read2);
2161 else
2162 CHECK_CALLED(Read);
2164 if(pcbRead) {
2165 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2166 *pcbRead = read;
2169 memset(pv, 'x', read);
2170 return hres;
2173 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2175 HRESULT hres;
2177 CHECK_EXPECT(MimeFilter_LockRequest);
2179 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2181 SET_EXPECT(LockRequest);
2182 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2183 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2184 CHECK_CALLED(LockRequest);
2186 return S_OK;
2189 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2191 HRESULT hres;
2193 CHECK_EXPECT(MimeFilter_UnlockRequest);
2195 SET_EXPECT(UnlockRequest);
2196 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2197 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2198 CHECK_CALLED(UnlockRequest);
2200 return S_OK;
2203 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2204 MimeProtocol_QueryInterface,
2205 Protocol_AddRef,
2206 Protocol_Release,
2207 MimeProtocol_Start,
2208 Protocol_Continue,
2209 Protocol_Abort,
2210 MimeProtocol_Terminate,
2211 Protocol_Suspend,
2212 Protocol_Resume,
2213 MimeProtocol_Read,
2214 Protocol_Seek,
2215 MimeProtocol_LockRequest,
2216 MimeProtocol_UnlockRequest
2219 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2221 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2223 ok(0, "unexpected call\n");
2224 return E_NOINTERFACE;
2227 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2229 return 2;
2232 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2234 return 1;
2237 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2238 REFIID riid, void **ppv)
2240 CHECK_EXPECT(CreateInstance);
2242 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2243 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
2244 ok(ppv != NULL, "ppv == NULL\n");
2246 *ppv = &Protocol;
2247 return S_OK;
2250 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2252 ok(0, "unexpected call\n");
2253 return S_OK;
2256 static const IClassFactoryVtbl ClassFactoryVtbl = {
2257 ClassFactory_QueryInterface,
2258 ClassFactory_AddRef,
2259 ClassFactory_Release,
2260 ClassFactory_CreateInstance,
2261 ClassFactory_LockServer
2264 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2266 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2268 CHECK_EXPECT(MimeFilter_CreateInstance);
2270 ok(!outer, "outer = %p\n", outer);
2271 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", debugstr_guid(riid));
2273 *ppv = &MimeProtocol;
2274 return S_OK;
2277 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2278 ClassFactory_QueryInterface,
2279 ClassFactory_AddRef,
2280 ClassFactory_Release,
2281 MimeFilter_CreateInstance,
2282 ClassFactory_LockServer
2285 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2287 #define TEST_BINDING 0x0001
2288 #define TEST_FILTER 0x0002
2289 #define TEST_FIRST_HTTP 0x0004
2290 #define TEST_DIRECT_READ 0x0008
2291 #define TEST_POST 0x0010
2292 #define TEST_EMULATEPROT 0x0020
2293 #define TEST_SHORT_READ 0x0040
2294 #define TEST_REDIRECT 0x0080
2295 #define TEST_ABORT 0x0100
2296 #define TEST_ASYNCREQ 0x0200
2297 #define TEST_USEIURI 0x0400
2298 #define TEST_IMPLPROTEX 0x0800
2299 #define TEST_EMPTY 0x1000
2300 #define TEST_NOMIME 0x2000
2302 static void register_filter(BOOL do_register)
2304 IInternetSession *session;
2305 HRESULT hres;
2307 hres = pCoInternetGetSession(0, &session, 0);
2308 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2310 if(do_register) {
2311 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2312 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2313 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2314 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2315 }else {
2316 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2317 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2318 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2319 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2322 IInternetSession_Release(session);
2325 static void init_test(int prot, DWORD flags)
2327 tested_protocol = prot;
2328 binding_test = (flags & TEST_BINDING) != 0;
2329 first_data_notif = TRUE;
2330 prot_read = 0;
2331 prot_state = 0;
2332 async_read_pending = TRUE;
2333 mimefilter_test = (flags & TEST_FILTER) != 0;
2334 no_mime = (flags & TEST_NOMIME) != 0;
2335 filter_state = 0;
2336 post_stream_read = 0;
2337 ResetEvent(event_complete);
2338 ResetEvent(event_complete2);
2339 ResetEvent(event_continue);
2340 ResetEvent(event_continue_done);
2341 async_protocol = binding_protocol = filtered_protocol = NULL;
2342 filtered_sink = NULL;
2343 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2344 first_data_notif = TRUE;
2345 state = STATE_CONNECTING;
2346 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2347 direct_read = (flags & TEST_DIRECT_READ) != 0;
2348 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2349 wait_for_switch = TRUE;
2350 short_read = (flags & TEST_SHORT_READ) != 0;
2351 http_post_test = TYMED_NULL;
2352 test_redirect = (flags & TEST_REDIRECT) != 0;
2353 test_abort = (flags & TEST_ABORT) != 0;
2354 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2355 empty_file = (flags & TEST_EMPTY) != 0;
2357 register_filter(mimefilter_test);
2360 static void test_priority(IInternetProtocol *protocol)
2362 IInternetPriority *priority;
2363 LONG pr;
2364 HRESULT hres;
2366 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2367 (void**)&priority);
2368 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2369 if(FAILED(hres))
2370 return;
2372 hres = IInternetPriority_GetPriority(priority, &pr);
2373 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2374 ok(pr == 0, "pr=%d, expected 0\n", pr);
2376 hres = IInternetPriority_SetPriority(priority, 1);
2377 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2379 hres = IInternetPriority_GetPriority(priority, &pr);
2380 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2381 ok(pr == 1, "pr=%d, expected 1\n", pr);
2383 IInternetPriority_Release(priority);
2386 static void test_early_abort(const CLSID *clsid)
2388 IInternetProtocol *protocol;
2389 HRESULT hres;
2391 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2392 &IID_IInternetProtocol, (void**)&protocol);
2393 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2395 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2396 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2398 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2399 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2401 IInternetProtocol_Release(protocol);
2404 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2405 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2407 HRESULT hres;
2409 SET_EXPECT(GetBindInfo);
2410 if(!(bindf & BINDF_FROMURLMON))
2411 SET_EXPECT(ReportProgress_DIRECTBIND);
2412 if(is_first) {
2413 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2414 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2415 if(bindf & BINDF_FROMURLMON)
2416 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2417 else
2418 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2420 SET_EXPECT(ReportData);
2421 if(is_first)
2422 SET_EXPECT(ReportResult);
2424 expect_hrResult = S_OK;
2426 if(protocolex) {
2427 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2428 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2429 }else {
2430 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2431 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2432 win_skip("Start failed\n");
2433 return FALSE;
2435 ok(hres == S_OK, "Start failed: %08x\n", hres);
2438 CHECK_CALLED(GetBindInfo);
2439 if(!(bindf & BINDF_FROMURLMON))
2440 CHECK_CALLED(ReportProgress_DIRECTBIND);
2441 if(is_first) {
2442 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2443 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2444 if(bindf & BINDF_FROMURLMON)
2445 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2446 else
2447 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2449 CHECK_CALLED(ReportData);
2450 if(is_first)
2451 CHECK_CALLED(ReportResult);
2453 return TRUE;
2456 static void test_file_protocol_url(LPCWSTR url)
2458 IInternetProtocolInfo *protocol_info;
2459 IUnknown *unk;
2460 IClassFactory *factory;
2461 IInternetProtocol *protocol;
2462 BYTE buf[512];
2463 ULONG cb;
2464 HRESULT hres;
2466 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2467 &IID_IUnknown, (void**)&unk);
2468 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2469 if(FAILED(hres))
2470 return;
2472 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2473 ok(hres == E_NOINTERFACE,
2474 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2476 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2477 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2478 IUnknown_Release(unk);
2479 if(FAILED(hres))
2480 return;
2482 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2483 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2485 if(SUCCEEDED(hres)) {
2486 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2487 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2488 ok(hres == S_OK, "Read failed: %08x\n", hres);
2489 ok(cb == 2, "cb=%u expected 2\n", cb);
2490 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2491 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2492 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2493 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2494 ok(cb == 0, "cb=%u expected 0\n", cb);
2495 hres = IInternetProtocol_UnlockRequest(protocol);
2496 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2499 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2500 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2501 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2502 hres = IInternetProtocol_LockRequest(protocol, 0);
2503 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2504 hres = IInternetProtocol_UnlockRequest(protocol);
2505 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2508 IInternetProtocol_Release(protocol);
2511 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2512 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2513 if(SUCCEEDED(hres)) {
2514 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2515 hres = IInternetProtocol_LockRequest(protocol, 0);
2516 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2517 hres = IInternetProtocol_Terminate(protocol, 0);
2518 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2519 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2520 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2521 hres = IInternetProtocol_UnlockRequest(protocol);
2522 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2523 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2524 ok(hres == S_OK, "Read failed: %08x\n", hres);
2525 hres = IInternetProtocol_Terminate(protocol, 0);
2526 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2529 IInternetProtocol_Release(protocol);
2532 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2533 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2534 if(SUCCEEDED(hres)) {
2535 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2536 hres = IInternetProtocol_Terminate(protocol, 0);
2537 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2538 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2539 ok(hres == S_OK, "Read failed: %08x\n", hres);
2540 ok(cb == 2, "cb=%u expected 2\n", cb);
2543 IInternetProtocol_Release(protocol);
2546 if(pCreateUri) {
2547 IInternetProtocolEx *protocolex;
2548 IUri *uri;
2550 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2551 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2553 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2554 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2556 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2557 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2558 ok(hres == S_OK, "Read failed: %08x\n", hres);
2559 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2560 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2561 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2562 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2565 IUri_Release(uri);
2566 IInternetProtocolEx_Release(protocolex);
2568 hres = pCreateUri(url, 0, 0, &uri);
2569 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2571 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2572 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2574 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2575 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2576 ok(hres == S_OK, "Read failed: %08x\n", hres);
2577 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2578 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2579 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2580 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2583 IUri_Release(uri);
2584 IInternetProtocolEx_Release(protocolex);
2585 }else {
2586 win_skip("Skipping file protocol StartEx tests\n");
2589 IClassFactory_Release(factory);
2592 static void test_file_protocol_fail(void)
2594 IInternetProtocol *protocol;
2595 HRESULT hres;
2597 static const WCHAR index_url2[] =
2598 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2600 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2601 &IID_IInternetProtocol, (void**)&protocol);
2602 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2603 if(FAILED(hres))
2604 return;
2606 SET_EXPECT(GetBindInfo);
2607 expect_hrResult = MK_E_SYNTAX;
2608 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2609 ok(hres == MK_E_SYNTAX ||
2610 hres == E_INVALIDARG,
2611 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2612 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2614 SET_EXPECT(GetBindInfo);
2615 if(!(bindf & BINDF_FROMURLMON))
2616 SET_EXPECT(ReportProgress_DIRECTBIND);
2617 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2618 SET_EXPECT(ReportResult);
2619 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2620 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2621 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2622 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2623 CHECK_CALLED(GetBindInfo);
2624 if(!(bindf & BINDF_FROMURLMON))
2625 CHECK_CALLED(ReportProgress_DIRECTBIND);
2626 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2627 CHECK_CALLED(ReportResult);
2629 IInternetProtocol_Release(protocol);
2631 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2632 &IID_IInternetProtocol, (void**)&protocol);
2633 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2634 if(FAILED(hres))
2635 return;
2637 SET_EXPECT(GetBindInfo);
2638 if(!(bindf & BINDF_FROMURLMON))
2639 SET_EXPECT(ReportProgress_DIRECTBIND);
2640 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2641 SET_EXPECT(ReportResult);
2642 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2644 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2645 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2646 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2647 CHECK_CALLED(GetBindInfo);
2648 if(!(bindf & BINDF_FROMURLMON))
2649 CHECK_CALLED(ReportProgress_DIRECTBIND);
2650 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2651 CHECK_CALLED(ReportResult);
2653 SET_EXPECT(GetBindInfo);
2654 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2655 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2656 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2658 SET_EXPECT(GetBindInfo);
2659 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2660 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2661 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2663 IInternetProtocol_Release(protocol);
2666 static void test_file_protocol(void) {
2667 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2668 DWORD size;
2669 ULONG len;
2670 HANDLE file;
2672 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2673 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2674 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2675 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2676 static const char html_doc[] = "<HTML></HTML>";
2678 trace("Testing file protocol...\n");
2679 init_test(FILE_TEST, 0);
2681 SetLastError(0xdeadbeef);
2682 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2683 FILE_ATTRIBUTE_NORMAL, NULL);
2684 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2685 if(file == INVALID_HANDLE_VALUE)
2686 return;
2687 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2688 CloseHandle(file);
2690 file_name = wszIndexHtml;
2691 bindf = 0;
2692 test_file_protocol_url(index_url);
2693 bindf = BINDF_FROMURLMON;
2694 test_file_protocol_url(index_url);
2695 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2696 test_file_protocol_url(index_url);
2698 memcpy(buf, wszFile, sizeof(wszFile));
2699 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2700 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2701 buf[len++] = '\\';
2702 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2704 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2705 bindf = 0;
2706 test_file_protocol_url(buf);
2707 bindf = BINDF_FROMURLMON;
2708 test_file_protocol_url(buf);
2710 memcpy(buf, wszFile2, sizeof(wszFile2));
2711 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2712 file_name_buf[len++] = '\\';
2713 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2714 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2715 file_name = file_name_buf;
2716 bindf = 0;
2717 test_file_protocol_url(buf);
2718 bindf = BINDF_FROMURLMON;
2719 test_file_protocol_url(buf);
2721 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2722 test_file_protocol_url(buf);
2724 memcpy(buf, wszFile3, sizeof(wszFile3));
2725 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2726 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2727 buf[len++] = '\\';
2728 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2730 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2731 bindf = 0;
2732 test_file_protocol_url(buf);
2733 bindf = BINDF_FROMURLMON;
2734 test_file_protocol_url(buf);
2736 memcpy(buf, wszFile4, sizeof(wszFile4));
2737 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2738 file_name_buf[len++] = '\\';
2739 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2740 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2741 file_name = file_name_buf;
2742 bindf = 0;
2743 test_file_protocol_url(buf);
2744 bindf = BINDF_FROMURLMON;
2745 test_file_protocol_url(buf);
2747 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2748 test_file_protocol_url(buf);
2750 DeleteFileW(wszIndexHtml);
2752 bindf = 0;
2753 test_file_protocol_fail();
2754 bindf = BINDF_FROMURLMON;
2755 test_file_protocol_fail();
2758 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2760 static BOOL got_user_agent = FALSE;
2761 IUri *uri = NULL;
2762 HRESULT hres;
2764 if(use_iuri && pCreateUri) {
2765 hres = pCreateUri(url, 0, 0, &uri);
2766 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2769 SET_EXPECT(GetBindInfo);
2770 if (!(bindf & BINDF_FROMURLMON))
2771 SET_EXPECT(ReportProgress_DIRECTBIND);
2772 if(!got_user_agent)
2773 SET_EXPECT(GetBindString_USER_AGENT);
2774 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2775 SET_EXPECT(QueryService_HttpNegotiate);
2776 SET_EXPECT(BeginningTransaction);
2777 SET_EXPECT(GetRootSecurityId);
2778 if(http_post_test) {
2779 SET_EXPECT(GetBindString_POST_COOKIE);
2780 if(http_post_test == TYMED_ISTREAM)
2781 SET_EXPECT(Stream_Seek);
2784 if(uri) {
2785 IInternetProtocolEx *protocolex;
2787 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2788 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2790 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2791 ok(hres == S_OK, "Start failed: %08x\n", hres);
2793 IInternetProtocolEx_Release(protocolex);
2794 IUri_Release(uri);
2795 }else {
2796 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2797 ok(hres == S_OK, "Start failed: %08x\n", hres);
2799 if(FAILED(hres))
2800 return FALSE;
2802 CHECK_CALLED(GetBindInfo);
2803 if (!(bindf & BINDF_FROMURLMON))
2804 CHECK_CALLED(ReportProgress_DIRECTBIND);
2805 if (!got_user_agent)
2807 CHECK_CALLED(GetBindString_USER_AGENT);
2808 got_user_agent = TRUE;
2810 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2811 CHECK_CALLED(QueryService_HttpNegotiate);
2812 CHECK_CALLED(BeginningTransaction);
2813 /* GetRootSecurityId called on WinXP but not on Win98 */
2814 CLEAR_CALLED(GetRootSecurityId);
2815 if(http_post_test) {
2816 CHECK_CALLED(GetBindString_POST_COOKIE);
2817 if(http_post_test == TYMED_ISTREAM)
2818 CHECK_CALLED(Stream_Seek);
2821 return TRUE;
2824 static void test_protocol_terminate(IInternetProtocol *protocol)
2826 BYTE buf[3600];
2827 DWORD cb;
2828 HRESULT hres;
2830 hres = IInternetProtocol_LockRequest(protocol, 0);
2831 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2833 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2834 ok(hres == test_abort ? S_OK : S_FALSE, "Read failed: %08x\n", hres);
2836 hres = IInternetProtocol_Terminate(protocol, 0);
2837 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2839 /* This wait is to give the internet handles being freed in Terminate
2840 * enough time to actually terminate in all cases. Internet handles
2841 * terminate asynchronously and native reuses the main InternetOpen
2842 * handle. The only case in which this seems to be necessary is on
2843 * wine with native wininet and urlmon, resulting in the next time
2844 * test_http_protocol_url being called the first data notification actually
2845 * being an extra last data notification from the previous connection
2846 * about once out of every ten times. */
2847 Sleep(100);
2849 hres = IInternetProtocol_UnlockRequest(protocol);
2850 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2853 static void test_http_info(IInternetProtocol *protocol)
2855 IWinInetHttpInfo *info;
2856 HRESULT hres;
2858 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2859 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2861 /* TODO */
2863 IWinInetHttpInfo_Release(info);
2866 /* is_first refers to whether this is the first call to this function
2867 * _for this url_ */
2868 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
2870 IInternetProtocolInfo *protocol_info;
2871 IClassFactory *factory;
2872 IUnknown *unk;
2873 HRESULT hres;
2875 init_test(prot, flags);
2876 http_url = url;
2877 http_post_test = tymed;
2879 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
2880 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
2881 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2882 if(FAILED(hres))
2883 return;
2885 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2886 ok(hres == E_NOINTERFACE,
2887 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
2888 hres);
2890 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2891 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2892 IUnknown_Release(unk);
2893 if(FAILED(hres))
2894 return;
2896 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
2897 (void**)&async_protocol);
2898 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2899 if(SUCCEEDED(hres)) {
2900 BYTE buf[3600];
2901 DWORD cb;
2902 ULONG ref;
2904 test_priority(async_protocol);
2905 test_http_info(async_protocol);
2907 SET_EXPECT(ReportProgress_COOKIE_SENT);
2908 if(http_is_first) {
2909 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
2910 SET_EXPECT(ReportProgress_CONNECTING);
2912 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2913 if(test_redirect)
2914 SET_EXPECT(ReportProgress_REDIRECTING);
2915 SET_EXPECT(ReportProgress_PROXYDETECTING);
2916 if(prot == HTTP_TEST)
2917 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2918 else
2919 SET_EXPECT(QueryService_HttpSecurity);
2920 if(!(bindf & BINDF_FROMURLMON)) {
2921 SET_EXPECT(OnResponse);
2922 SET_EXPECT(ReportProgress_RAWMIMETYPE);
2923 SET_EXPECT(ReportData);
2924 } else {
2925 SET_EXPECT(Switch);
2928 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0))
2929 return;
2931 if(!direct_read && !test_abort)
2932 SET_EXPECT(ReportResult);
2933 expect_hrResult = test_abort ? E_ABORT : S_OK;
2935 if(direct_read) {
2936 SET_EXPECT(Switch);
2937 while(wait_for_switch) {
2938 WaitForSingleObject(event_continue, INFINITE);
2939 CHECK_CALLED(Switch); /* Set in ReportData */
2940 call_continue(&continue_protdata);
2941 SetEvent(event_continue_done);
2943 }else {
2944 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
2945 ok((hres == E_PENDING && cb==0) ||
2946 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
2948 WaitForSingleObject(event_complete, INFINITE);
2949 if(bindf & BINDF_FROMURLMON)
2950 CHECK_CALLED(Switch);
2951 else
2952 CHECK_CALLED(ReportData);
2953 if(prot == HTTPS_TEST)
2954 CLEAR_CALLED(QueryService_HttpSecurity);
2956 while(1) {
2957 if(bindf & BINDF_FROMURLMON)
2958 SET_EXPECT(Switch);
2959 else
2960 SET_EXPECT(ReportData);
2961 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
2962 if(hres == E_PENDING) {
2963 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
2964 ok((hres == E_PENDING && cb==0) ||
2965 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
2966 WaitForSingleObject(event_complete, INFINITE);
2967 if(bindf & BINDF_FROMURLMON)
2968 CHECK_CALLED(Switch);
2969 else
2970 CHECK_CALLED(ReportData);
2972 if(test_abort) {
2973 HRESULT hres;
2975 SET_EXPECT(ReportResult);
2976 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
2977 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2978 CHECK_CALLED(ReportResult);
2980 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
2981 ok(hres == INET_E_RESULT_DISPATCHED, "Abort failed: %08x\n", hres);
2982 break;
2984 }else {
2985 if(bindf & BINDF_FROMURLMON)
2986 CHECK_NOT_CALLED(Switch);
2987 else
2988 CHECK_NOT_CALLED(ReportData);
2989 if(cb == 0) break;
2992 if(!test_abort) {
2993 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2994 CHECK_CALLED(ReportResult);
2997 if(prot == HTTPS_TEST)
2998 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3000 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3001 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3003 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3004 ok(hres == INET_E_RESULT_DISPATCHED, "Abort failed: %08x\n", hres);
3006 test_protocol_terminate(async_protocol);
3008 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3009 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3011 ref = IInternetProtocol_Release(async_protocol);
3012 ok(!ref, "ref=%x\n", ref);
3015 IClassFactory_Release(factory);
3018 static void test_http_protocol(void)
3020 static const WCHAR posttest_url[] =
3021 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3022 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3023 static const WCHAR redirect_url[] =
3024 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3025 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3026 static const WCHAR winetest_url[] =
3027 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3028 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3029 static const WCHAR empty_url[] =
3030 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3031 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3033 trace("Testing http protocol (not from urlmon)...\n");
3034 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3035 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3037 trace("Testing http protocol (from urlmon)...\n");
3038 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3039 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3041 trace("Testing http protocol (to file)...\n");
3042 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3043 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3045 trace("Testing http protocol (post data)...\n");
3046 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3047 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3049 trace("Testing http protocol (post data stream)...\n");
3050 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3052 trace("Testing http protocol (direct read)...\n");
3053 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3054 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3056 trace("Testing http protocol (redirected)...\n");
3057 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3058 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3060 trace("Testing http protocol empty file...\n");
3061 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3063 trace("Testing http protocol abort...\n");
3064 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3066 test_early_abort(&CLSID_HttpProtocol);
3067 test_early_abort(&CLSID_HttpSProtocol);
3070 static void test_https_protocol(void)
3072 static const WCHAR codeweavers_url[] =
3073 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
3074 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0};
3076 trace("Testing https protocol (from urlmon)...\n");
3077 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3078 test_http_protocol_url(codeweavers_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3082 static void test_ftp_protocol(void)
3084 IInternetProtocolInfo *protocol_info;
3085 IClassFactory *factory;
3086 IUnknown *unk;
3087 BYTE buf[4096];
3088 ULONG ref;
3089 DWORD cb;
3090 HRESULT hres;
3092 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3093 '/','p','u','b','/','o','t','h','e','r','/',
3094 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3096 trace("Testing ftp protocol...\n");
3098 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3099 state = STATE_STARTDOWNLOADING;
3100 tested_protocol = FTP_TEST;
3101 first_data_notif = TRUE;
3102 expect_hrResult = E_PENDING;
3104 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3105 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3106 if(FAILED(hres))
3107 return;
3109 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3110 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3112 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3113 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3114 IUnknown_Release(unk);
3115 if(FAILED(hres))
3116 return;
3118 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3119 (void**)&async_protocol);
3120 IClassFactory_Release(factory);
3121 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3123 test_priority(async_protocol);
3124 test_http_info(async_protocol);
3126 SET_EXPECT(GetBindInfo);
3127 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3128 SET_EXPECT(ReportProgress_CONNECTING);
3129 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3130 SET_EXPECT(Switch);
3132 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
3133 ok(hres == S_OK, "Start failed: %08x\n", hres);
3134 CHECK_CALLED(GetBindInfo);
3136 SET_EXPECT(ReportResult);
3138 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3139 ok((hres == E_PENDING && cb==0) ||
3140 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3142 WaitForSingleObject(event_complete, INFINITE);
3144 while(1) {
3145 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3146 if(hres == E_PENDING)
3147 WaitForSingleObject(event_complete, INFINITE);
3148 else
3149 if(cb == 0) break;
3152 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3153 CHECK_CALLED(ReportResult);
3154 CHECK_CALLED(Switch);
3156 test_protocol_terminate(async_protocol);
3158 if(pCreateUri) {
3159 IInternetProtocolEx *protocolex;
3161 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3162 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3163 IInternetProtocolEx_Release(protocolex);
3166 ref = IInternetProtocol_Release(async_protocol);
3167 ok(!ref, "ref=%d\n", ref);
3169 test_early_abort(&CLSID_FtpProtocol);
3172 static void test_gopher_protocol(void)
3174 IInternetProtocolInfo *protocol_info;
3175 IClassFactory *factory;
3176 IUnknown *unk;
3177 HRESULT hres;
3179 trace("Testing gopher protocol...\n");
3181 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3182 ok(hres == S_OK ||
3183 hres == REGDB_E_CLASSNOTREG, /* Gopher protocol has been removed as of Vista */
3184 "CoGetClassObject failed: %08x\n", hres);
3185 if(FAILED(hres))
3186 return;
3188 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3189 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3191 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3192 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3193 IUnknown_Release(unk);
3194 if(FAILED(hres))
3195 return;
3197 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3198 (void**)&async_protocol);
3199 IClassFactory_Release(factory);
3200 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3202 test_priority(async_protocol);
3204 IInternetProtocol_Release(async_protocol);
3206 test_early_abort(&CLSID_GopherProtocol);
3209 static void test_mk_protocol(void)
3211 IInternetProtocolInfo *protocol_info;
3212 IInternetProtocol *protocol;
3213 IClassFactory *factory;
3214 IUnknown *unk;
3215 HRESULT hres;
3217 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
3218 ':',':','/','t','e','s','t','.','h','t','m','l',0};
3219 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
3221 trace("Testing mk protocol...\n");
3222 init_test(MK_TEST, 0);
3224 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
3225 &IID_IUnknown, (void**)&unk);
3226 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3228 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3229 ok(hres == E_NOINTERFACE,
3230 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3231 hres);
3233 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3234 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3235 IUnknown_Release(unk);
3236 if(FAILED(hres))
3237 return;
3239 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3240 (void**)&protocol);
3241 IClassFactory_Release(factory);
3242 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3244 SET_EXPECT(GetBindInfo);
3245 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
3246 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
3247 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
3248 CLEAR_CALLED(GetBindInfo);
3250 SET_EXPECT(GetBindInfo);
3251 SET_EXPECT(ReportProgress_DIRECTBIND);
3252 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3253 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3254 SET_EXPECT(ReportResult);
3255 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3257 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
3258 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
3259 hres == INET_E_INVALID_URL, /* win2k3 */
3260 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
3262 if (hres == INET_E_RESOURCE_NOT_FOUND) {
3263 CHECK_CALLED(GetBindInfo);
3264 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3265 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3266 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3267 CHECK_CALLED(ReportResult);
3268 }else {
3269 CLEAR_CALLED(GetBindInfo);
3270 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3271 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3272 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3273 CLEAR_CALLED(ReportResult);
3276 IInternetProtocol_Release(protocol);
3279 static void test_CreateBinding(void)
3281 IInternetProtocol *protocol;
3282 IInternetPriority *priority;
3283 IInternetSession *session;
3284 IWinInetHttpInfo *http_info;
3285 IWinInetInfo *inet_info;
3286 LONG p;
3287 BYTE buf[1000];
3288 DWORD read;
3289 HRESULT hres;
3291 static const WCHAR test_url[] =
3292 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
3293 static const WCHAR wsz_test[] = {'t','e','s','t',0};
3295 trace("Testing CreateBinding...\n");
3296 init_test(BIND_TEST, TEST_BINDING);
3298 hres = pCoInternetGetSession(0, &session, 0);
3299 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3301 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
3302 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3304 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3305 binding_protocol = protocol;
3306 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3307 ok(protocol != NULL, "protocol == NULL\n");
3309 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3310 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3312 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3313 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
3315 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
3316 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3317 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
3318 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3319 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3320 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3322 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
3323 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
3325 p = 0xdeadbeef;
3326 hres = IInternetPriority_GetPriority(priority, &p);
3327 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3328 ok(!p, "p=%d\n", p);
3330 ex_priority = 100;
3331 hres = IInternetPriority_SetPriority(priority, 100);
3332 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3334 p = 0xdeadbeef;
3335 hres = IInternetPriority_GetPriority(priority, &p);
3336 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3337 ok(p == 100, "p=%d\n", p);
3339 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3340 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3342 SET_EXPECT(QueryService_InternetProtocol);
3343 SET_EXPECT(CreateInstance);
3344 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3345 SET_EXPECT(SetPriority);
3346 SET_EXPECT(Start);
3348 expect_hrResult = S_OK;
3349 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3350 ok(hres == S_OK, "Start failed: %08x\n", hres);
3352 CHECK_CALLED(QueryService_InternetProtocol);
3353 CHECK_CALLED(CreateInstance);
3354 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3355 CHECK_CALLED(SetPriority);
3356 CHECK_CALLED(Start);
3358 SET_EXPECT(QueryInterface_IWinInetInfo);
3359 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3360 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3361 CHECK_CALLED(QueryInterface_IWinInetInfo);
3363 SET_EXPECT(QueryInterface_IWinInetInfo);
3364 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3365 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3366 CHECK_CALLED(QueryInterface_IWinInetInfo);
3368 SET_EXPECT(QueryInterface_IWinInetHttpInfo);
3369 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
3370 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3371 CHECK_CALLED(QueryInterface_IWinInetHttpInfo);
3373 SET_EXPECT(Read);
3374 read = 0xdeadbeef;
3375 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3376 ok(hres == S_OK, "Read failed: %08x\n", hres);
3377 ok(read == 100, "read = %d\n", read);
3378 CHECK_CALLED(Read);
3380 SET_EXPECT(Read);
3381 read = 0xdeadbeef;
3382 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3383 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3384 ok(!read, "read = %d\n", read);
3385 CHECK_CALLED(Read);
3387 p = 0xdeadbeef;
3388 hres = IInternetPriority_GetPriority(priority, &p);
3389 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3390 ok(p == 100, "p=%d\n", p);
3392 hres = IInternetPriority_SetPriority(priority, 101);
3393 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3395 SET_EXPECT(Terminate);
3396 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
3397 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3398 CHECK_CALLED(Terminate);
3400 SET_EXPECT(Continue);
3401 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
3402 ok(hres == S_OK, "Switch failed: %08x\n", hres);
3403 CHECK_CALLED(Continue);
3405 hres = IInternetProtocolSink_ReportProgress(binding_sink,
3406 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
3407 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
3409 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
3410 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
3412 hres = IInternetProtocolSink_ReportData(binding_sink, 0, 0, 0);
3413 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
3415 IInternetProtocolSink_Release(binding_sink);
3416 IInternetPriority_Release(priority);
3417 IInternetBindInfo_Release(prot_bind_info);
3418 IInternetProtocol_Release(protocol);
3420 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3421 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3422 ok(protocol != NULL, "protocol == NULL\n");
3424 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3425 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3427 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
3428 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3430 IInternetProtocol_Release(protocol);
3432 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, wsz_test);
3433 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3435 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3436 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3437 ok(protocol != NULL, "protocol == NULL\n");
3439 SET_EXPECT(QueryService_InternetProtocol);
3440 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3441 ok(hres == MK_E_SYNTAX, "Start failed: %08x, expected MK_E_SYNTAX\n", hres);
3442 CHECK_CALLED(QueryService_InternetProtocol);
3444 IInternetProtocol_Release(protocol);
3446 IInternetSession_Release(session);
3449 static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
3451 IInternetProtocolEx *protocolex = NULL;
3452 IInternetProtocol *protocol;
3453 IInternetSession *session;
3454 IUri *uri = NULL;
3455 ULONG ref;
3456 HRESULT hres;
3458 pi = grf_pi;
3460 init_test(prot, test_flags|TEST_BINDING);
3462 hres = pCoInternetGetSession(0, &session, 0);
3463 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3465 if(test_flags & TEST_EMULATEPROT) {
3466 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
3467 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3470 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
3471 binding_protocol = protocol;
3472 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3473 ok(protocol != NULL, "protocol == NULL\n");
3475 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3476 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3478 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3479 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
3481 if(test_flags & TEST_USEIURI) {
3482 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3483 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3485 hres = pCreateUri(binding_urls[prot], Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
3486 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3489 ex_priority = 0;
3490 SET_EXPECT(QueryService_InternetProtocol);
3491 SET_EXPECT(CreateInstance);
3492 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3493 SET_EXPECT(SetPriority);
3494 if(impl_protex)
3495 SET_EXPECT(StartEx);
3496 else
3497 SET_EXPECT(Start);
3499 expect_hrResult = S_OK;
3501 if(protocolex) {
3502 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, pi, 0);
3503 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
3504 }else {
3505 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0);
3506 ok(hres == S_OK, "Start failed: %08x\n", hres);
3509 CHECK_CALLED(QueryService_InternetProtocol);
3510 CHECK_CALLED(CreateInstance);
3511 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3512 CHECK_CALLED(SetPriority);
3513 if(impl_protex)
3514 CHECK_CALLED(StartEx);
3515 else
3516 CHECK_CALLED(Start);
3518 if(protocolex)
3519 IInternetProtocolEx_Release(protocolex);
3520 if(uri)
3521 IUri_Release(uri);
3523 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
3524 while(prot_state < 4) {
3525 WaitForSingleObject(event_complete, INFINITE);
3526 if(mimefilter_test && filtered_protocol) {
3527 SET_EXPECT(Continue);
3528 IInternetProtocol_Continue(filtered_protocol, pdata);
3529 CHECK_CALLED(Continue);
3530 }else {
3531 SET_EXPECT(Continue);
3532 IInternetProtocol_Continue(protocol, pdata);
3533 CHECK_CALLED(Continue);
3535 if(test_abort && prot_state == 2) {
3536 SET_EXPECT(Abort);
3537 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3538 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3539 CHECK_CALLED(Abort);
3541 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3542 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3543 SetEvent(event_complete2);
3544 break;
3546 SetEvent(event_complete2);
3548 if(direct_read)
3549 CHECK_CALLED(ReportData); /* Set in ReportResult */
3550 WaitForSingleObject(event_complete, INFINITE);
3551 }else {
3552 if(mimefilter_test)
3553 SET_EXPECT(MimeFilter_LockRequest);
3554 else
3555 SET_EXPECT(LockRequest);
3556 hres = IInternetProtocol_LockRequest(protocol, 0);
3557 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3558 if(mimefilter_test)
3559 CHECK_CALLED(MimeFilter_LockRequest);
3560 else
3561 CHECK_CALLED(LockRequest);
3563 if(mimefilter_test)
3564 SET_EXPECT(MimeFilter_UnlockRequest);
3565 else
3566 SET_EXPECT(UnlockRequest);
3567 hres = IInternetProtocol_UnlockRequest(protocol);
3568 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3569 if(mimefilter_test)
3570 CHECK_CALLED(MimeFilter_UnlockRequest);
3571 else
3572 CHECK_CALLED(UnlockRequest);
3575 if(mimefilter_test)
3576 SET_EXPECT(MimeFilter_Terminate);
3577 else
3578 SET_EXPECT(Terminate);
3579 hres = IInternetProtocol_Terminate(protocol, 0);
3580 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3581 if(mimefilter_test)
3582 CLEAR_CALLED(MimeFilter_Terminate);
3583 else
3584 CHECK_CALLED(Terminate);
3586 if(filtered_protocol)
3587 IInternetProtocol_Release(filtered_protocol);
3588 IInternetBindInfo_Release(prot_bind_info);
3589 IInternetProtocolSink_Release(binding_sink);
3590 ref = IInternetProtocol_Release(protocol);
3591 ok(!ref, "ref=%u, expected 0\n", ref);
3593 if(test_flags & TEST_EMULATEPROT) {
3594 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]);
3595 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3598 IInternetSession_Release(session);
3601 START_TEST(protocol)
3603 HMODULE hurlmon;
3605 hurlmon = GetModuleHandle("urlmon.dll");
3606 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
3607 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
3608 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3610 if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3611 win_skip("Various needed functions not present, too old IE\n");
3612 return;
3615 if(!pCreateUri)
3616 win_skip("CreateUri not supported\n");
3618 OleInitialize(NULL);
3620 event_complete = CreateEvent(NULL, FALSE, FALSE, NULL);
3621 event_complete2 = CreateEvent(NULL, FALSE, FALSE, NULL);
3622 event_continue = CreateEvent(NULL, FALSE, FALSE, NULL);
3623 event_continue_done = CreateEvent(NULL, FALSE, FALSE, NULL);
3624 thread_id = GetCurrentThreadId();
3626 test_file_protocol();
3627 test_http_protocol();
3628 test_https_protocol();
3629 test_ftp_protocol();
3630 test_gopher_protocol();
3631 test_mk_protocol();
3632 test_CreateBinding();
3634 bindf &= ~BINDF_FROMURLMON;
3635 trace("Testing file binding (mime verification, emulate prot)...\n");
3636 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3637 trace("Testing http binding (mime verification, emulate prot)...\n");
3638 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3639 trace("Testing its binding (mime verification, emulate prot)...\n");
3640 test_binding(ITS_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3641 trace("Testing http binding (mime verification, emulate prot, short read, direct read)...\n");
3642 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_SHORT_READ|TEST_DIRECT_READ);
3643 trace("Testing file binding (mime verification, emulate prot, mime filter)...\n");
3644 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3645 trace("Testing http binding (mime verification, emulate prot, mime filter)...\n");
3646 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3647 trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n");
3648 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME);
3649 trace("Testing http binding (mime verification, emulate prot, direct read)...\n");
3650 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
3651 trace("Testing http binding (mime verification, emulate prot, abort)...\n");
3652 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
3653 if(pCreateUri) {
3654 trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
3655 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);
3656 trace("Testing file binding (use IUri, impl StartEx, mime verification, emulate prot)...\n");
3657 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI|TEST_IMPLPROTEX);
3658 trace("Testing file binding (impl StartEx, mime verification, emulate prot)...\n");
3659 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_IMPLPROTEX);
3662 CloseHandle(event_complete);
3663 CloseHandle(event_complete2);
3664 CloseHandle(event_continue);
3665 CloseHandle(event_continue_done);
3667 OleUninitialize();